【问题标题】:EOF in Windows command prompt doesn't terminate input streamWindows 命令提示符中的 EOF 不会终止输入流
【发布时间】:2011-09-10 17:30:25
【问题描述】:

代码:

#include <stdio.h>
#define NEWLINE '\n'
#define SPACE ' '

int main(void)
{
    int ch;
    int count = 0;

    while((ch = getchar()) != EOF)
    {
        if(ch != NEWLINE  && ch != SPACE)
            count++;
    }
    printf("There are %d characters input\n" , count);

    return 0;
}

问题:

  1. 一切正常,它会忽略空格和换行符并输出输入到屏幕的字符数(在这个程序中,我只是将逗号、感叹号、数字或任何可打印的特殊符号字符(如&符号)视为字符太)当我点击^z的EOF模拟时。

  2. 但是当我将这一行输入到程序时出现了问题。例如我输入这个:abcdefg^z,这意味着我在^z之前和同一行输入了一些字符。程序不会终止程序并打印出总字符数,而是会继续请求输入。

  3. EOF 终止字符输入仅在我在单行上指定 ^z 或通过执行以下操作时才有效:^zabvcjdjsjsj。为什么会这样?

【问题讨论】:

    标签: c eof


    【解决方案1】:

    几乎每个终端驱动程序都是如此。使用 Linux,您将获得相同的行为。

    在您在行尾输入\n^z 之前,您的程序实际上并没有执行循环。终端驱动程序正在缓冲输入,直到发生这种情况才将其发送到您的进程。

    在行尾,点击^z(或Linux 上的^d不会导致终端驱动程序发送EOF。它只会使它将缓冲区刷新到您的进程(没有\n)。

    在一行的开头点击^z(或Linux 上的^d)会被终端解释为“我想发出EOF 信号”。

    如果您在循环中添加以下内容,您可以观察到这种行为:

    printf("%d\n",ch);
    

    运行你的程序:

    $ ./test
    abc                      <- type "abc" and hit "enter"
    97
    98
    99
    10
    abc97                    <- type "abc" and hit "^z"
    98
    99
    

    为了更好地理解这一点,您必须意识到 EOF 不是字符。 ^z终端本身的用户命令。因为终端负责获取用户输入并将其传递给进程,所以这会变得很棘手,因此会造成混乱。

    查看这一点的一种方法是点击^v,然后点击^z作为程序的输入。

    ^v 是另一个终端命令,它告诉终端:“嘿,我输入的下一个命令 - 不要将其解释为终端命令;而是将其传递给进程的输入”。

    【讨论】:

    • 非常感谢。我对在终端中打印两次以及我的程序的其他一些奇怪行为感到非常困惑。所以从你的回答中,我发现第一个打印是终端驱动程序,第二个是我的程序,在按下 Enter 键之后。谢谢!!!!
    【解决方案2】:

    ^Z 仅在行首输入时由控制台转换为程序的 EOF 信号。这就是 Windows 控制台的工作方式。据我所知,这种行为没有“解决方法”。

    【讨论】:

    • 那么为什么当我将^z放在一行中的字符流之后时,它不被算作一个字符呢?例如“abcdefg^z”只返回“有7个字符 inpit”而不是在我在那一行之后输入 ^z 之后的 8 个。
    • @caramel23:我相信 Windows 控制台只是忽略它并且不会将字符传递给正在运行的程序。我不知道为什么会这样。
    猜你喜欢
    • 2017-06-20
    • 2015-01-31
    • 1970-01-01
    • 1970-01-01
    • 2016-10-12
    • 2021-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多