当-1无法在char中表示时,为什么EOF定义为-1?

时间:2015-11-11 14:19:15

标签: c char eof

我在树莓派上学习C编程,但是我发现我的程序从未成功捕获EOF。我使用char c=0; printf("%d",c-1);来测试char类型,发现char类型的范围是0到255,unsigned short。但EOF中定义的stdio.h为(-1)。我的Pi上安装了错误的cc包吗?我该怎么解决?如果我手动更改了EOF中的stdio.h值,还会有其他问题吗?

令我担心的是,当我从K& R书中学习时,有一些例子使用像while ((c=getchar())!=EOF)之类的代码,我在我的Ubuntu机器上遵循了它,它运行正常。我只是想知道现代C语言是否放弃了这种语法,或者我的Raspberry Pi中是否存在冲突?

这是我的代码:

#include <stdio.h>
int main( void )
{
        char c;
        int i=0;
        while ((c=getchar())!=EOF&&i<50) {
                putchar(c);
                i++;
        }
        if (c==EOF)
                printf("\nEOF got.\n");
        while ((c=getchar())!=EOF&&i<500) {
                printf("%d",c);
                i++;
        }
}

即使我将输入重定向到文件,它仍然在屏幕上打印255,永远不会终止此程序。

最后我发现我错了,在K&amp; R书中,它将c定义为int,而不是char。问题解决了。

4 个答案:

答案 0 :(得分:5)

您需要将fgetc()getchar()等所读取的字符存储在int中,以便您可以抓住EOF。这是众所周知的,到处都是如此。 EOF必须与所有正确的字符区分开来,因此决定像fgetc()这样的函数将有效字符作为非负值返回(即使char已签名)。文件结束条件由-1发出信号,该条件为负数,因此不会与任何有效字符fgetc()发生冲突。

不要编辑系统头文件,尤其是不要更改那里定义的常量值。如果你这样做,你就打破了这些标题。请注意,即使您更改了标头中EOF的值,也不会更改值fgetc()的函数返回文件结束或错误,它只会使{{1有错误的值。

答案 1 :(得分:2)

  

为什么当-1不能用char表示时,EOF定义为-1?

因为EOF不是字符而是状态。

答案 2 :(得分:2)

  

如果我手动更改了stdio.h中的EOF值,还会有更多   问题

当然,因为你会完全打破标题。标题不是实际的函数,只是一组原型和其他地方定义的函数的声明绝对不要改变系统标题,除了破坏代码,项目和/或更糟糕的事情之外,你永远不会成功做任何事情。

关于EOF的主题:EOF不是一个字符,因此不能用字符变量表示。为了解决这个问题,大多数程序员只使用一个int值(默认签名)来解释EOF中的-1。 EOF永远不能成为一个字符的原因是因为否则会有一个字符与文件结尾指示符无法区分。

答案 3 :(得分:1)

intchar

fgetc()会返回int,而非char。返回的值在unsigned charEOF范围内。这通常是257个不同的值。因此,将结果保存在char, signed char, unsigned char中会有所区别。

而是将fgetc()返回值保存在int中。 测试EOF结果后,如果需要,该值可以保存为char

// char c;
int c;
...
while ((c=getchar())!=EOF&&i<50) {
  char ch = c;
  ...

详细信息:“当{1}}中无法表示-1时,为什么EOF被定义为-1?”误导。在char已签名且char的系统上,EOF == -1 可以的值为char。然而在这样的系统上,EOF的值可以为-1,表示一个字符 - 它们重叠。因此,char无法明确代表所有charchar。最好使用EOF来保存int的返回值。

  

... fgetc函数将该字符转换为fgetc()转换为unsigned char并且...   如果设置了流的文件结束指示符,或者流位于文件结尾,则...并且fgetc函数返回int。 ......C11§7.21.7.12-3