6

This example is from the K&R book

#include<stdio.h>


main()
{
    long nc;

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

enter image description here

Could you explain me why it works that way. Thanks.

^Z^Z doesn't work either (unless it's in the beginning of a line)

enter image description here

4

4 回答 4

1

传统的 UNIX 对 tty 字符的解释是在读取熟 tty 行缓冲区中缓冲的任何内容后EOF使阻塞返回。read在新行的开头,这意味着read返回 0(读取零字节),顺便提一下,0-sizedread是如何检测普通文件的文件结束条件。

这就是为什么行中间的 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 运行时库模仿了上述语义(在 Windows 上没有调用^Z级别的特殊处理kernel32,更不用说系统调用了)。这就是为什么它可能会^Z^Z在输入行中间检测到 EOF 的原因。

于 2013-01-21T11:00:17.027 回答
0

EOF该程序将仅在输入的实际结束时读取。如果您的终端/OS/whatever 只允许文件在行首结束,那么您可以在此处找到它们。我相信这是对老式终端的回归,其中数据一次只传输一行(据我所知,它可以追溯到打孔卡阅读器)。

尝试从预先准备好的 EOF 中线文件中读取数据。您甚至可能会发现某些编辑器使这变得困难!作为输入,您的程序应该可以正常工作。

于 2013-01-21T13:25:09.923 回答
0

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

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

于 2013-01-21T13:57:52.947 回答
0

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

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

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

PS:问题发生在您使用getchar(). 我认为这个答案更容易理解,但可能不适合你,因为它是从中文翻译过来的......

于 2013-01-25T09:00:45.447 回答