*注意:我正在使用Windows,所以EOF对我来说是ctrl + Z.
有一段时间我注意到EOF输入在隔离方面的行为似乎与其他输入时相同。例如,^Z
(命令提示符中的Windows的EOF命令)和a^Z
似乎在以下代码中导致不同的行为:
#include <stdio.h>
#define MAX 1000
int getline(char s[]);
main() {
int line;
char arr[MAX];
while( (line = getline(arr)) != EOF)
printf("%s",arr);
system("Pause");
return 0;
}
int getline(char s[])
{
int c, i = 0;
while ((c = getchar()) != EOF && c != '\n') {
s[i++] = c;
}
if (c == '\n') {
s[i++] = c;
}
else
return EOF;
s[i] = '\0';
return 1;
}
如果我在命令提示符下输入^Z
+,则程序可预测地跳转到system("Pause");
但是,如果我输入abc^Z
+输入,则没有任何反应,就好像EOF被忽略一样从未收到'\n'
命令。如果此时我再次按回车键,则会显示以下内容:
我一直在修补和调试这段代码及其小变种一个多小时,现在似乎找不到任何问题。从理论上讲,如果我输入abc^Z
+输入,我希望输入被解释为abcEOF\n
,这将给出:
s[0] = 'a'
s[1] = 'b'
s[2] = 'c'
i = 3 when loop breaks from c = EOF
if (c == '\n') skipped since c = EOF
leads to else -> return EOF
in main(), line = EOF since that is what the function getline returned
while loop breaks because of above
system("Pause"); follows
我的代码是否有问题,我忽略了或者是否有一些我要注意的EOF或命令提示的怪癖?我几乎可以肯定,这不是将^Z
与其他值混合导致意外行为的唯一情况。
答案 0 :(得分:4)
不要将 CTRL-Z 视为文件结尾字符,实际上有一个带有代码点的真实字符26(这是你通常期望的 CTRL-Z 生成)。
相反,请将 CTRL-Z 视为终端设备指示程序输入流结束的一种方式。如果您要读取磁盘的真实文件并且它包含 CTRL-Z ,它应该继续(尽管在某些实现中可能不是这种情况,例如,使用模式r
而不是rb
打开它。
在Windows中, CTRL-Z 到端流操作的转换仅在它出现在行的 start 时发生,这就是为什么你不是输入abcCTRL-Z
时获取EOF。
当你在不是行的开头的字符位置输入 CTRL-Z 时,它被视为真正的 CTRL-Z ,不是流关闭操作。这就是为什么你得到→
字符,这是代码点26的可打印字符。
答案 1 :(得分:0)
这是 getchar ..
的正常行为getchar ()是标准功能,需要您按 * ENTER *才能获得输入
许多编译器/平台支持不需要ENTER的非标准 getch ()。
EOF不是角色。 EOF是getchar()在到达输入结尾或遇到某种错误时返回的宏