伴随其他值时的EOF行为

*注意:我正在使用Windows,所以EOF对我来说是ctrl + Z.

有一段时间我注意到,EOF输入在隔离方面的行为似乎与其他输入时相同。 例如, ^Z (命令提示符中的Windows的EOF命令)和a^Z似乎在以下代码中导致不同的行为:

 #include  #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 + enter,则没有任何反应,好像EOF被忽略并且从未收到'\n'命令。 如果,此时我再次按回车键,则显示以下内容:

EOF奇怪

我一直在修补和调试这段代码及其小变种一个多小时了,现在似乎找不到任何问题。 理论上,如果我输入abc^Z + enter,我希望输入被解释为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与其他值混合导致意外行为的唯一情况。

不要认为CTRL-Z是文件结尾字符,实际上有一个代码点26的真实字符(这是你通常期望CTRL-Z生成的)。

相反,可以将CTRL-Z视为终端设备指示程序输入流结束的一种方式。 如果您要读取磁盘的真实文件并且它包含CTRL-Z ,它应该继续(尽管在某些实现中可能不是这种情况,例如,您使用模式r而不是rb打开它)。

在Windows中, CTRL-Z到端流操作的转换仅在它出现在行的开头时发生,这就是当你输入abc CTRL-Z时没有得到EOF的原因。

当您在不是行的开头的字符位置上输入CTRL-Z时,它被视为真正的CTRL-Z ,而不是流关闭操作。 这就是为什么你得到那个字符,这是代码点26的可打印字符。

这是getchar的正常行为..

getchar ()是一个标准函数,需要你 * ENTER *来获取输入

许多编译器/平台支持不需要ENTER的非标准getch ()。

EOF不是一个角色。 EOF是getchar()在到达输入结尾或遇到某种错误时返回的宏