6

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 Enter在提示符下键入

输出是:

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

为什么会导致ungetc()失败?

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

4

1 回答 1

4

工作在以下假设:

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

该调用与C11 7.21.7.10/4 所涵盖的行为ungetc('\xFF', stdin);相同:ungetc(EOF, stdin);

如果 的值c等于宏的值EOF,则操作失败,输入流不变。


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


关于 的值'\xFF',见 C11 6.4.4.4/10:

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

此外,执行字符集的值是实现定义的 (C11 5.2.1/1)。您可以检查编译器文档以确定,但编译器行为表明它255不在执行字符集中;事实上,我测试的 gcc 版本的行为表明它将范围char作为执行字符集(而不是范围unsigned char)。

于 2018-06-14T23:33:33.070 回答