ungetc

来自cppreference.com
< c‎ | io
 
 
文件输入/输出
类型与对象
函数
文件访问
直接输入/输出
无格式输入/输出
(C95)(C95)
(C95)
(C95)(C95)
(C95)
(C95)
有格式输入
 
在标头 <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)
{
    while (*fmt != '\0')
    {
        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);
                    break;
                case 'c':
                    c = getc(s);
                    printf("%%c scanned '%c'\n", c);
                    break;
            }
        }
        else
            ++fmt;
    }
}
 
int main(void)
{
    FILE* f = fopen("input.txt", "w+");
    if (f != NULL)
    {
        fputs("123x", f);
        rewind(f);
        demo_scanf("%u%c", f);
        fclose(f);
    }
    return 0;
}

输出:

%u scanned 123
%c scanned 'x'

引用

  • C23 标准(ISO/IEC 9899:2024):
  • 7.21.7.10 The ungetc function (第 TBD 页)
  • C17 标准(ISO/IEC 9899:2018):
  • 7.21.7.10 The ungetc function (第 243 页)
  • C11 标准(ISO/IEC 9899:2011):
  • 7.21.7.10 The ungetc function (第 334 页)
  • C99 标准(ISO/IEC 9899:1999):
  • 7.19.7.11 The ungetc function (第 300 页)
  • C89/C90 标准(ISO/IEC 9899:1990):
  • 4.9.7.11 The ungetc function

参阅

从文件流获取一个字符
(函数)