77

我目前正在阅读 Ritchie & Kernighan 的《C Programming Language》一书。getchar()而且我对函数中 EOF 的使用感到非常困惑。

首先,我想知道为什么 EOF 的值为-1,为什么值为getchar()!=EOF0。请原谅我的问题,但我真的不明白。我真的试过了,但我做不到。

然后我尝试运行书中的示例,该示例可以使用下面的代码计算字符数,但似乎即使我按下回车,我也永远不会退出循环,所以我想知道我什么时候会到达 EOF?

main(){
   long nc;
   nc = 0;
   while (getchar() != EOF)
       ++nc;
   printf("%ld\n", nc);
}

然后,我在Problem with EOF in C阅读了同样的问题。大多数人建议不要使用 EOF,而是使用终止符 \n 或空终止符 '\0',这很有意义。

这是否意味着书中的例子有另一个目的?

4

3 回答 3

105

EOF 表示“文件结束”。换行符(当您按下回车键时会发生这种情况)不是文件的结尾,而是的结尾,因此换行符不会终止此循环。

代码没有错[*],它只是没有按照您的预期进行。它读取到输入的末尾,但您似乎只想读取到一行的末尾。

EOF 的值为 -1,因为它必须不同于任何返回值,因为它getchar是一个实际字符。因此getchar将任何字符值作为无符号字符返回,转换为 int,因此将是非负数。

如果您在终端上键入并且想要触发文件结尾,请使用 CTRL-D(unix 样式系统)或 CTRL-Z(Windows)。然后在读取所有输入后,getchar()将返回EOF,因此getchar() != EOF将为假,循环将终止。

[*] 好吧,如果由于整数溢出而导致输入超过 LONG_MAX 个字符,它具有未定义的行为,但我们可以在一个简单的示例中原谅这一点。

于 2010-12-05T12:26:06.080 回答
22

EOF 是-1,因为它是这样定义的。该名称由您提供的标准库头文件提供#include。它们使它等于 -1,因为它必须是不能被误认为是getchar(). getchar()使用正数(包括 0 到 255)报告实际字节的值,因此 -1 可以正常工作。

运算符的!=意思是“不等于”。0 代表假,其他代表真。所以发生的事情是,我们调用该getchar()函数,并将结果与​​ -1 (EOF) 进行比较。如果结果不等于 EOF,则结果为真,因为不相等的事物不相等。如果结果等于 EOF,则结果为假,因为相等的事物不(不相等)。

getchar()当您到达“文件末尾”时,调用返回 EOF。就 C 而言,“标准输入”(您通过在命令窗口中输入给程序的数据)就像一个文件。当然,你总是可以输入更多,所以你需要一种明确的方式来表达“我完成了”。在 Windows 系统上,这是 control-Z。在 Unix 系统上,这是 control-D。

书中的例子并没有“错误”。这取决于您实际想要做什么。阅读直到 EOF 意味着您阅读了所有内容,直到用户说“我完成了”,然后您就无法再阅读了。读到 '\n' 意味着你读了一行输入。如果您希望用户键入输入,则读取到 '\0' 是一个坏主意,因为在命令提示符下使用键盘生成此字节很难或不可能:)

于 2010-12-05T12:26:40.093 回答
9

这是很多问题。

  1. 为什么EOF是-1:POSIX系统调用中的-1通常会在错误时返回,所以我猜这个想法是“EOF是一种错误”

  2. 任何布尔运算(包括!=)在它为 TRUE 的情况下返回 1,在它为 FALSE 的情况下返回 0,当它为 FALSE 时getchar() != EOF也是如此0,意思是getchar()返回EOF

  3. 为了EOF在从stdin新闻中阅读时效仿Ctrl+D

于 2010-12-05T12:24:22.587 回答