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系统上测试了相同的代码,并且它在那里表现得如预期的那样。是否存在某种未定义的行为?
答案 0 :(得分:4)
进行以下假设:
'\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:
包含不映射到单字节执行字符的字符或转义序列的整数字符常量[...]的值是实现定义的。
此外,执行字符集的值是实现定义的(C11 5.2.1 / 1)。您可以检查编译器文档以确定,但编译器行为表明255
不在执行字符集中;事实上,我测试的gcc版本的行为表明它需要char
的范围作为执行字符集(而不是unsigned char
的范围)。