#include<stdio.h>
main()
{
long nc;
nc = 0;
while(getchar() != EOF)
++nc;
printf("%ld\n", nc);
}
你能解释一下为什么它会这样工作吗?谢谢。
^Z^Z也不起作用(除非它在一行的开头)
#include<stdio.h>
main()
{
long nc;
nc = 0;
while(getchar() != EOF)
++nc;
printf("%ld\n", nc);
}
你能解释一下为什么它会这样工作吗?谢谢。
^Z^Z也不起作用(除非它在一行的开头)
传统的UNIX解释tty EOF
字符是在读取缓存在烹饪tty行缓冲区内的任何内容后使阻塞read
返回。在新行的开头,这意味着read
返回0(读取零字节),巧合的是,0大小的read
是普通文件上检测到文件结束条件的方式。
这就是为什么在一行中的第一个EOF
只是强制开始读取该行,而不是使C运行时库检测到文件结束的原因。两个EOF
字符连续出现会产生0大小的读取,因为第二个强制应用程序读取一个空缓冲区。
$ 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上,kernel32
调用甚至系统调用都没有对^Z
进行特殊处理)。这就是为什么它可能会在输入行的中间检测到^Z^Z
后面的EOF。
EOF
。如果您的终端/操作系统/任何其他东西只允许文件在行的开头结束,那么您将在那里找到它们。我认为这是对老式终端的回溯,其中数据仅一次传输一行(据我所知,这可以追溯到打孔卡片阅读器)。EOF 表示“文件结束”。换行符(当您按下回车键时发生的情况)不是文件的结尾,而是行的结尾,因此换行符不会终止此循环。
根据操作系统的不同,EOF
字符只有在它是一行中的第一个字符时才能起作用,即在 Enter
后的第一个字符。由于控制台输入通常是面向行的,因此系统可能也无法识别 EOF
字符,直到您跟随其后输入了 Enter
。
我碰巧和你有同样的问题。当我想结束函数getchar()
时,我必须输入2个EOF
或输入一个<ENTER>
加上一个EOF
。
这里是我搜索到的更简单的答案:
如果终端中有字符输入,EOF将起到停止此输入的作用,这将引起新的输入;而如果没有输入发生,或者换句话说,当getchar()正在等待新的回车(例如您刚刚完成输入或EOF),您即将输入的EOF等于“文件结尾”,这将导致程序停止执行函数getchar()。
PS:这个问题发生在使用getchar()
时。我认为这个答案更容易理解,但可能对你来说不是这样,因为它是从中文翻译过来的...