std::ungetc
来自 cppreference.com
定义在头文件 <cstdio> 中 |
||
int ungetc( int ch, std::FILE *stream ); |
||
如果 ch
不等于 EOF,则将字符 ch
(重新解释为 unsigned char)推入与流 stream
关联的输入缓冲区,以使后续对 stream
的读取操作将检索该字符。与流关联的外部设备不会被修改。
流重新定位操作 std::fseek、std::fsetpos 和 std::rewind 会丢弃 ungetc
的效果。
如果在进行一次读取或重新定位操作之前多次调用 ungetc
,它可能会失败(换句话说,保证有大小为 1 的回退缓冲区,但任何更大的缓冲区都是实现定义的)。如果执行了多次成功的 ungetc
,则读取操作将按 ungetc
的反向顺序检索回退的字符。
如果 ch
等于 EOF,则操作失败,流不受影响。
对 ungetc
的成功调用会清除文件结束状态标志 std::feof。
对二进制流上的 ungetc
的成功调用会将流位置指示器减 1(如果流位置指示器为零,则行为是不确定的)。
对文本流上的 ungetc
的成功调用会以未指定的方式修改流位置指示器,但保证在所有回退的字符都通过读取操作检索后,流位置指示器将等于其在 ungetc
之前的数值。
内容 |
[编辑] 参数
ch | - | 要推入输入流缓冲区的字符 |
stream | - | 将字符放回的文件流 |
[编辑] 返回值
成功时返回 ch
。
失败时返回 EOF,给定的流保持不变。
[编辑] 注释
回退缓冲区的大小在实践中从 4k(Linux、MacOS)到仅 4(Solaris)或保证的最小值 1(HPUX、AIX)不等。
如果回退的字符等于外部字符序列中该位置的字符,则回退缓冲区的表观大小可能更大(实现可能只减少读取文件位置指示器,而不维护回退缓冲区)。
[编辑] 示例
演示了 std::ungetc
在其原始用途中的使用:实现 std::scanf
运行此代码
#include <cctype> #include <cstdio> void demo_scanf(const char* fmt, std::FILE* s) { while (*fmt != '\0') { if (*fmt == '%') { switch (*++fmt) { case 'u': { int c{}; while (std::isspace(c=std::getc(s))) {} unsigned int num{}; while (std::isdigit(c)) { num = num*10 + c-'0'; c = std::getc(s); } std::printf("%%u scanned %u\n", num); std::ungetc(c, s); break; } case 'c': { int c = std::getc(s); std::printf("%%c scanned '%c'\n", c); break; } } } else { ++fmt; } } } int main() { if (std::FILE* f = std::fopen("input.txt", "w+")) { std::fputs("123x", f); std::rewind(f); demo_scanf("%u%c", f); std::fclose(f); } }
输出
%u scanned 123 %c scanned 'x'
[编辑] 另请参阅
从文件流中获取一个字符 (函数) | |
C 文档 针对 ungetc
|