ungetc()
似乎在某些字符上失败。这是一个简单的测试程序:
#include <stdio.h>
int main(void) {
int c;
printf("Type a letter and the enter key: ");
#define TRACE(x) printf("%s -> %dn", #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
为什么导致ungetc()
失败?
编辑:更糟糕的是,我在不同的Unix系统上测试了相同的代码,它的行为符合预期。是否存在某种未定义的行为?
基于以下假设:
- 您使用的是对纯字符进行签名的系统。
'xFF'
-1
在您的系统上(超出范围的字符常量的值是实现定义的,见下文(。EOF
-1
在您的系统上。
调用ungetc('xFF', stdin);
与 C11 7.21.7.10/4 涵盖其行为的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
的范围(。