伴随其他值时的EOF行为

时间:2013-06-18 06:43:48

标签: c command prompt eof

*注意:我正在使用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'命令。如果此时我再次按回车键,则会显示以下内容:

EOF weirdness

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

2 个答案:

答案 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()在到达输入结尾或遇到某种错误时返回的宏