代码之家  ›  专栏  ›  技术社区  ›  chqrlie

为什么ungetc在某些角色上失败?

  •  6
  • chqrlie  · 技术社区  · 8 年前

    ungetc() 在某些角色上似乎失败了。下面是一个简单的测试程序:

    #include <stdio.h>
    
    int main(void) {
        int c;
    
        printf("Type a letter and the enter key: ");
    
    #define TRACE(x)  printf("%s -> %d\n", #x, x)
        TRACE(c = getc(stdin));
        TRACE(ungetc(c, stdin));
        TRACE(getc(stdin));
    
        TRACE(ungetc('\xFE', stdin));
        TRACE(getc(stdin));
    
        TRACE(ungetc('\xFF', stdin));
        TRACE(getc(stdin));
    
        return 0;
    }
    

    我在unix系统上运行它并键入 a 进入 在提示下

    输出为:

    Type a letter and the enter key: a
    c = getc(stdin) -> 97
    ungetc(c, stdin) -> 97
    getc(stdin) -> 97
    ungetc('\xFE', stdin) -> 254
    getc(stdin) -> 254
    ungetc('\xFF', stdin) -> -1
    getc(stdin) -> 10
    

    我预料到:

    Type a letter and the enter key: a
    c = getc(stdin) -> 97
    ungetc(c, stdin) -> 97
    getc(stdin) -> 97
    ungetc('\xFE', stdin) -> 254
    getc(stdin) -> 254
    ungetc('\xFF', stdin) -> 255
    getc(stdin) -> 255
    

    为什么导致 UNGET() 失败?

    编辑: 更糟糕的是,我在不同的unix系统上测试了相同的代码,它的行为与预期一致。是否有某种未定义的行为?

    1 回复  |  直到 8 年前
        1
  •  4
  •   M.M    8 年前

    进行以下假设:

    • 你在一个签名为普通字符的系统上。
    • '\xFF' -1 在您的系统上(超出范围字符常量的值是由实现定义的,请参见下文)。
    • EOF - 1 在你的系统上。

    呼叫 ungetc('\xFF', stdin); ungetc(EOF, stdin); 其行为被C11 7.21.7.10/4所涵盖:

    如果 c 等于宏的 EOF ,操作失败,输入流未更改。


    的输入范围 ungetc 与的输出范围相同 getchar ,即 EOF 是负数,或表示字符的非负数(负数字符通过转换为 unsigned char )。我想你是想 ungetc(255, stdin);


    关于 \xFF ,见C11 6.4.4.4/10:

    包含未映射到单字节执行字符的字符或转义序列的整数字符常量[…]的值是由实现定义的。

    此外,执行字符集的值是由实现定义的(C115.2.1/1)。您可以检查编译器文档以确定,但编译器行为表明 255 不在执行字符集中;事实上,我测试的gcc版本的行为表明 char 作为执行字符集(不是 无符号字符 )