ungetc
ungetc
在头文件 | | |
---|---|---|
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
二进制流将流位置指示符递减1(如果流位置指示符为零,则行为不确定)。
ungetc
在文本流上的成功调用以未指定的方式修改流位置指示符,但保证在用读取操作检索到所有后推字符后,流位置指示符等于其之前的值ungetc
。
参数
CH | - | 字符被压入输入流缓冲区 |
---|---|---|
流 | - | 文件流将字符放回 |
返回值
成功则返回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))) {} // skip leading white space
unsigned int num = 0;
while(isdigit(c)) {
num = num*10 + c-'0';
c = getc(s
}
printf("%%u scanned %u\n", num
ungetc(c, s // reprocess the non-digit
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标准(ISO / IEC 9899:2011):