C语言 为什么 ungetc 在某些字符上失败?



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的范围(。

相关内容

  • 没有找到相关文章

最新更新