ungetc

来自cppreference.com
< c‎ | io
定义于头文件 <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) {
    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); // 重处理非数字
            case 'c': c = getc(s);
                      printf("%%c scanned '%c'\n", c);
        }
    } 
}
 
int main(void)
{
    FILE* f = fopen("input.txt", "w+");
    fputs("123x", f);
    rewind(f); 
    demo_scanf("%u%c", f);
    fclose(f);
}

输出:

%u scanned 123
%c scanned 'x'

[编辑] 参考

  • C11 standard (ISO/IEC 9899:2011):
  • 7.21.7.10 The ungetc function (p: 334)
  • C99 standard (ISO/IEC 9899:1999):
  • 7.19.7.11 The ungetc function (p: 300)
  • C89/C90 standard (ISO/IEC 9899:1990):
  • 4.9.7.11 The ungetc function

[编辑] 参阅

从文件流获取一个字符
(函数) [edit]
ungetcC++文档