为什么getchar()仅在行的开头识别EOF?

这个例子来自K&R书

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

在此处输入图像描述

你能解释一下为什么它会这样运作吗? 谢谢。

^ Z ^ Z也不起作用(除非它在一行的开头)

在此处输入图像描述

tty EOF字符的传统UNIX解释是在读取在烹饪的tty行缓冲区内缓冲的内容之后使阻塞read返回。 在新行的开头,它表示read返回0(读取零字节),顺便说一下,0大小的read是检测普通文件上文件结束条件的方式。

这就是为什么行中间的第一个 EOF强制read行的开头,而不是让C运行时库检测到文件的结尾。 一行中的两个 EOF字符产生0大小的读取,因为第二个EOF字符强制应用程序read空缓冲区。

 $ cat foo[press ^D]foo <=== after ^D, input printed back before EOL, despite cooked mode. No EOF detected foo[press ^D]foo[press ^D] <=== after first ^D, input printed back, and on second ^D, cat detects EOF $ cat Some first line <=== input Some first line <=== the line is read and printed [press ^D] <=== at line start, ^D forces 0-sized read to happen, cat detects EOF 

我假设您的C运行时库模仿上面描述的语义(在Windows上调用级别没有特别处理^Z ,更不用说Windows上的系统调用)。 这就是为什么即使在输入线的中间它也可能在^Z^Z之后检测到EOF。

程序将仅在输入的实际结束时读取EOF 。 如果您的终端/操作系统/任何只允许文件在一行开头结束,那么您就可以找到它们。 我相信这是老式终端的倒退,数据一次只传输一行(据我所知,它可以追溯到穿孔读卡器)。

尝试从您使用EOF中线准备的文件中读取数据。 你甚至可能会发现有些编辑会让这很困难! 你的程序应该可以正常工作作为输入。

EOF表示“文件结束”。 换行符(当你按Enter键时会发生这种情况)不是文件的结尾,它是一行的结尾,所以换行符不会终止此循环。

根据操作系统的不同, EOF字符只有在一行中的第一个字符(即Enter后面的第一个字符)才有效。 由于控制台输入通常是面向行的,因此系统在您按Enter之后才会识别EOF字符。

我碰巧和你有同样的问题。 当我想结束函数getchar() ,我必须输入2 EOF或输入加上EOF

这是我搜索这个问题的一个更简单的答案:

如果终端中有字符进入,EOF将起到阻止此进入的作用,这将引起新的进入; 而如果没有进入,或者换句话说,当getchar()等待新的输入(例如你刚刚完成输入或EOF)时,你现在要输入的EOF等于“结束”文件“,这将导致程序停止执行函数getchar()。

PS:当你使用getchar()时会出现问题。 我认为这个答案更容易理解,但也许不适合你,因为它是从中文翻译出来的……