C 中的文件结尾 (EOF)

Posted

技术标签:

【中文标题】C 中的文件结尾 (EOF)【英文标题】:End of File (EOF) in C 【发布时间】:2011-05-20 12:18:41 【问题描述】:

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

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

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

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

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

这是否意味着书中的示例有其他用途?

【问题讨论】:

你知道你提到的这本书是C语言的原作者写的吧? 【参考方案1】:

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

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

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

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

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

【讨论】:

我现在知道问题所在了..这就是为什么我看不到结果..这是因为我使用的是 Dev-C++ 并且它没有系统(“暂停”)所以我需要输入在代码的末尾。 实际上 CTRL+D 不会引发 EOF。它只是终止您的终端,而内核又知道无法读取更多字节,因此标准输入文件描述符中没有可用的数据。 @newbie system 函数创建一个新的 shell 并运行传递给它的命令。该命令由系统shell执行,与编译器无关 如果你按回车键 'enter', 'getchar()' 只看到一个字符并且你的 'nc' 变量增加了。 @KorayTugay Bash 的行为是在收到来自 control-D 的 EOF 字符时退出 shell:unix.stackexchange.com/questions/110240/…【参考方案2】:

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

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

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

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

【讨论】:

【参考方案3】:

这是很多问题。

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

    任何布尔运算(包括!=)在它为真时返回1,在它为假时返回0,所以getchar() != EOF0当它为假时,意味着getchar()返回EOF

    为了在从stdin 读取时模拟EOF,请按Ctrl+D

【讨论】:

布尔运算返回 非零 为真,零为假。有区别。 不,运算符被定义为返回 1。任何非零值在布尔上下文中都是“真”(例如,if()while() 条件)。

以上是关于C 中的文件结尾 (EOF)的主要内容,如果未能解决你的问题,请参考以下文章

检查 string::getline 中的 eof

C 语言文件操作 ( 文件结尾判定 )

关于C语言读取文件结尾的问题

EOF是什么

C++怎么用eof判断txt文件到文件结尾了没

EOF是什么?