C 参考手册
- C 语言
- C 关键词
- 预处理器
- C 标准库头文件
- 类型支持
- 程序支持工具
- 变参数函数
- 错误处理
- 动态内存管理
- 日期和时间工具
- 字符串库
- 算法
- 数值
- 文件输入/输出
- gets, gets_s
- printf, fprintf, sprintf, snprintf, printf_s, fprintf_s, sprintf_s, snprintf_s
- fopen, fopen_s
- fputc, putc
- fputs
- getchar
- putchar
- FILE
- fpos_t
- stdin, stdout, stderr
- freopen, freopen_s
- fwide
- setbuf
- setvbuf
- fclose
- fflush
- fread
- fwrite
- fgetc, getc
- fgets
- puts
- ungetc
- fgetwc
- fgetws
- fputwc, putwc
- fputws
- getwchar
- putwchar
- ungetwc
- scanf, fscanf, sscanf, scanf_s, fscanf_s, sscanf_s
- wscanf, fwscanf, swscanf, wscanf_s, fwscanf_s, swscanf_s
- vscanf, vfscanf, vsscanf, vscanf_s, vfscanf_s, vsscanf_s
- vwscanf, vfwscanf, vswscanf, vwscanf_s, vfwscanf_s, vswscanf_s
- wprintf, fwprintf, swprintf, wprintf_s, fwprintf_s, swprintf_s, snwprintf_s
- vprintf, vfprintf, vsprintf, vsnprintf, vprintf_s, vfprintf_s, vsprintf_s, vsnprintf_s
- vwprintf, vfwprintf, vswprintf, vwprintf_s, vfwprintf_s, vswprintf_s, vsnwprintf_s
- ftell
- fgetpos
- fseek
- fsetpos
- rewind
- clearerr
- feof
- ferror
- perror
- remove
- rename
- tmpfile, tmpfile_s
- tmpnam, tmpnam_s
- 本地化支持
- 原子操作库
- 线程支持库
- 实验性 C 标准库
- 有用的资源
- 符号索引
- 注释
ungetc
定义于头文件 <stdio.h>
|
||
int ungetc( int ch, FILE *stream ); |
||
若 ch
不等于 EOF ,则推入字符 ch
(转译为 unsigned char )到与流 stream
关联的输入缓冲区,方式满足从 stream
的后继读取操作将取得该字符。不修改与流关联的外部设备。
流重寻位操作 fseek 、 fsetpos 和 rewind 弃去 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
参阅
从文件流获取一个字符 (函数) |