我是一名新程序员,正在阅读 K&R 的“ANSI C”第二版书。该示例具有以下程序,该程序使用 getchar() 对字符进行计数,直到达到 EOF。
include <stdio.h>
int main()
{
double nc;
for (nc = 0; getchar() !=EOF; ++nc)
;
printf("%.0f\n", nc);
}
编译并运行后(使用记事本和终端),我可以输入“123456789”,按回车键(什么也没有发生),然后输入Ctrl+Z,然后再次按回车键,程序终止,结果为10(合理的结果,但我不确定它是否将第 10 个字符算作 Ctrl、“Z”、“Ctrl+Z”或 Enter 键...我怀疑它是 Enter 键)。如果我尝试输入“123456789CtrlZ”+“Enter”,则什么也不会发生。如果我唯一的输入是“Ctrl+Z”然后是“Enter”,则程序将以 0(预期)结果终止。
我也在 CLion 中运行这个程序,但我无法满足 EOF,我必须手动中止该程序,因此我从未获得字符计数(我尝试过 Ctrl+Z、Ctrl+D、Enter、ESC、组合所有等等)
这个主题在某种程度上涵盖了here,这有帮助,但并不能完全满足我的问题。我知道我不需要知道 EOF 的实际值(打印为“-1”)。这更多的是关于该程序如何执行的实际问题。我假设 for 循环不会执行,直到我输入一串字符后按“Enter”,但是:
欣赏这方面的任何智慧。除非我完全理解每个示例,否则我会尽量不要继续阅读本书。
为什么“123456789CtrlZ”+“Enter”不会导致 main() 完全执行并输出 9?
因为 Ctrl-Z 除了一行中的第一个字符之外的任何位置都与任何其他字符一样。它在 Windows 世界中的值为 26,而
EOF
的值为 -1。
但是,当您在一行上按 Ctrl-Z first 时,会将
EOF
放入输入缓冲区中。由于输入是行缓冲的,因此您必须按 Return 才能获得 EOF
。会话可能如下所示:
hello world<Return>
this is fun<Return>
<Ctrl-Z><Return>
输出:
24
示例中的前两次 Return 按键将被计数。
EOF 字符(Windows 中的 CTRL-Z;Linux 和 Unix 中的 CTRL-D)仅当它是一行中的第一个字符时才有效。如果您已经输入了某些内容,则会被忽略。这就是为什么当您已经在一行中输入“123456789”时它没有任何效果。
顺便说一下,你计算的第十个字符是换行符( ),而不是 EOF 字符。如果有疑问 - 为学生做练习! - 将传入的字符读入缓冲区而不是丢弃它们,并在收到换行符或 EOF 时对每行进行十六进制转储。 (提示:小心缓冲区溢出!)
顺便说一句,我会回应其他人的评论。如果您想学习 C,一旦您从 K&R 学习了基础知识,就应该立即转向现代版本(C17 或 C23)。