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。它只是终止您的终端,而内核又知道无法读取更多字节,因此标准输入文件描述符中没有可用的数据。 @newbiesystem
函数创建一个新的 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() != EOF
是0
当它为假时,意味着getchar()
返回EOF
。
为了在从stdin
读取时模拟EOF
,请按Ctrl+D
【讨论】:
布尔运算返回 非零 为真,零为假。有区别。 不,运算符被定义为返回 1。任何非零值在布尔上下文中都是“真”(例如,if()
或 while()
条件)。以上是关于C 中的文件结尾 (EOF)的主要内容,如果未能解决你的问题,请参考以下文章