命名空间
变体
操作

ungetc

来自 cppreference.com
< c‎ | io
 
 
文件输入/输出
类型和对象
函数
文件访问
直接输入/输出
非格式化输入/输出
(直到 C11)(C11)
ungetc
(C95)(C95)
(C95)
(C95)(C95)
(C95)
(C95)
格式化输入
(C99)(C99)(C99)(C11)(C11)(C11)     
 
定义于头文件 <stdio.h>
int ungetc( int ch, FILE* stream );

如果 ch 不等于 EOF,则将字符 ch(重新解释为 unsigned char)压入与流 stream 关联的输入缓冲区,以使得后续从 stream 中的读取操作将检索该字符。与流关联的外部设备不会被修改。

流重定位操作 fseekfsetposrewind 会丢弃 ungetc 的效果。

如果在没有进行中间读取或重定位操作的情况下多次调用 ungetc,它可能会失败(换句话说,保证了大小为 1 的回推缓冲区,但任何更大的缓冲区都是实现定义的)。如果执行了多个成功的 ungetc,读取操作将以 ungetc 的逆序检索回推的字符。

如果 ch 等于 EOF,操作将失败,流不会受到影响。

成功调用 ungetc 将清除文件结束状态标志 feof

对二进制流成功调用 ungetc 会将流位置指示器递减一个(如果流位置指示器为零,则行为是不确定的)。

对文本流成功调用 ungetc 会以未指定的方式修改流位置指示器,但保证在使用读取操作检索所有回推的字符后,流位置指示器将等于其在 ungetc 之前的值。

内容

[编辑] 参数

ch - 要压入输入流缓冲区的字符
stream - 将字符放回的文件流

[编辑] 返回值

成功时返回 ch

失败时返回 EOF,并且给定的流保持不变。

[编辑] 备注

回推缓冲区的大小在实践中从 4k(Linux、MacOS)到 4(Solaris)或保证的最小值 1(HPUX、AIX)不等。

如果回推的字符等于外部字符序列中该位置的现有字符,则回推缓冲区的明显大小可能会更大(实现可能只需递减读取文件位置指示器并避免维护回推缓冲区)。

[编辑] 示例

演示 ungetc 的最初目的:实现 scanf

#include <ctype.h>
#include <stdio.h>
 
void demo_scanf(const char* fmt, FILE* s)
{
    while (*fmt != '\0')
    {
        if (*fmt == '%')
        {
            int c;
            switch (*++fmt)
            {
                case 'u':
                    while (isspace(c=getc(s))) {}
                    unsigned int num = 0;
                    while (isdigit(c))
                    {
                        num = num*10 + c-'0';
                        c = getc(s);
                    }
                    printf("%%u scanned %u\n", num);
                    ungetc(c, s);
                    break;
                case 'c':
                    c = getc(s);
                    printf("%%c scanned '%c'\n", c);
                    break;
            }
        }
        else
            ++fmt;
    }
}
 
int main(void)
{
    FILE* f = fopen("input.txt", "w+");
    if (f != NULL)
    {
        fputs("123x", f);
        rewind(f);
        demo_scanf("%u%c", f);
        fclose(f);
    }
    return 0;
}

输出

%u scanned 123
%c scanned 'x'

[编辑] 参考

  • C23 标准 (ISO/IEC 9899:2024)
  • 7.21.7.10 ungetc 函数 (p: TBD)
  • C17 标准 (ISO/IEC 9899:2018)
  • 7.21.7.10 ungetc 函数 (p: 243)
  • C11 标准 (ISO/IEC 9899:2011)
  • 7.21.7.10 ungetc 函数 (p: 334)
  • C99 标准 (ISO/IEC 9899:1999)
  • 7.19.7.11 ungetc 函数 (p: 300)
  • C89/C90 标准 (ISO/IEC 9899:1990)
  • 4.9.7.11 ungetc 函数

[编辑] 另请参阅

从文件流中获取一个字符
(函数) [编辑]
C++ 文档 适用于 ungetc