std:: ungetc
| I/O manipulators | ||||
| Print functions (C++23) | ||||
| C-style I/O | ||||
| Buffers | ||||
|
(C++23)
|
||||
|
(
C++98/26*
)
|
||||
|
(C++20)
|
||||
| Streams | ||||
| Abstractions | ||||
| File I/O | ||||
| String I/O | ||||
| Array I/O | ||||
|
(C++23)
|
||||
|
(C++23)
|
||||
|
(C++23)
|
||||
|
(
C++98/26*
)
|
||||
|
(
C++98/26*
)
|
||||
|
(
C++98/26*
)
|
||||
| Synchronized Output | ||||
|
(C++20)
|
||||
| Types | ||||
| Error category interface | ||||
|
(C++11)
|
||||
|
(C++11)
|
| Types and objects | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Functions | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
定义于头文件
<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
调用成功时,流位置指示器将递减一(若流位置指示器原为零则行为未定义)。
对文本流成功调用
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
|
|