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

时间:2013-01-21 10:24:34

标签: c eof

这个例子来自K& R书

#include<stdio.h>


main()
{
    long nc;

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

enter image description here

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

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

enter image description here

4 个答案:

答案 0 :(得分:1)

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

这就是为什么行中间的第一个 EOF只会强制该行的开头为read,而不会使C运行时库检测到文件末尾。 一行中的两个 EOF字符产生0大小的读取,因为第二个字符强制应用程序将空缓冲区设为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<CR> <=== 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运行时库模仿了上面描述的语义(在^Z调用级别没有kernel32的特殊处理,更不用说Windows上的系统调用了。这就是为什么即使在输入线的中间它也可能在^Z^Z之后检测到EOF。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

根据操作系统的不同,EOF字符只有在一行中的第一个字符即Enter之后的第一个字符时才有效。由于控制台输入通常是面向行的,因此在您使用EOF跟进后,系统可能无法识别Enter字符。

答案 3 :(得分:0)

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

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

  

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

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