C 为什么要用EOF清空stdin

C 为什么要用EOF清空stdin,c,C,冲洗stdin有很多问题,我的问题不在于如何冲洗,而在于以下功能的含义: while((c = getchar()) != '\n' && c != EOF); 我试图想一想为什么以及如何在这个函数中使用EOF来清空stdin?用户键入一些内容并按enter键,然后清空缓冲区直到找到enter键,EOF从何而来 多谢各位 编辑: 非常感谢你的第一个回答和第二个评论,这回答了我的问题,完全让我满意 除了我们从一个有真正EOF的文件中管道输入的场景(这几乎回答了我的问题)之外,我仍

冲洗stdin有很多问题,我的问题不在于如何冲洗,而在于以下功能的含义:

while((c = getchar()) != '\n' && c != EOF);
我试图想一想为什么以及如何在这个函数中使用EOF来清空stdin?用户键入一些内容并按enter键,然后清空缓冲区直到找到enter键,EOF从何而来

多谢各位

编辑: 非常感谢你的第一个回答和第二个评论,这回答了我的问题,完全让我满意


除了我们从一个有真正EOF的文件中管道输入的场景(这几乎回答了我的问题)之外,我仍然不理解为什么我们在任何其他场景中需要EOF来实现这样的函数。用户只能在终端中的行首调用EOF,因此它不能用于清空缓冲区。

如果用户在Linux/OS X上插入Ctrl-D或在Windows上插入Ctrl-Z,则可以从stdin获得EOF。此外,标准输入可能会从文件重定向-在这种情况下,最后您会得到一个真正的EOF


在这两种情况下,如果没有检查,循环将永远继续,等待永远不会出现的换行符在此处插入忧郁的音乐。

如果用户在Linux/OS X上插入Ctrl-D或在Windows上插入Ctrl-Z,您将从stdin获得EOF。此外,标准输入可能会从文件重定向-在这种情况下,最后您会得到一个真正的EOF

在这两种情况下,如果没有这个检查,循环将永远继续,等待一个永远不会出现的换行,在这里插入忧郁的音乐。

您的代码不会刷新stdin。它所做的只是搜索最近的“\n”或输入的结尾,以先到者为准

您可以在几种情况下获得EOF:

最终用户按下组合键关闭stdin,意味着下一次尝试读取将返回EOF,或 当输入通过操作系统特定的方式重定向以访问文件而不是使用控制台时,您到达了文件的实际结尾,例如a.out您的代码不会刷新标准输入。它所做的只是搜索最近的“\n”或输入的结尾,以先到者为准

您可以在几种情况下获得EOF:

最终用户按下组合键关闭stdin,意味着下一次尝试读取将返回EOF,或
当输入通过特定于操作系统的方式重定向以访问文件而不是使用控制台时,即到达文件的实际结尾,例如a.out您呈现的语句从stdin读取当前行的剩余部分并丢弃它,无论该行是以换行符“\n”结尾还是在流EOF的结尾。正如dasblinkenlight观察到的那样,这不是传统上所谓的同花顺

getchar在流结束或出错时返回EOF,EOF!='\n',所以如果没有EOF检查,该语句将在到达流的末尾时无限循环


输入的最后一行是否会换行终止,这一点并不确定。事实上,您可能会争辩说流的最后一行是在流的结尾处终止的,因此最后一行永远不会以换行符终止,尽管它可能包含零个字符。

您呈现的语句从stdin读取当前行的剩余部分并丢弃它,该行是以换行符“\n”结尾还是在流EOF的结尾。正如dasblinkenlight观察到的那样,这不是传统上所谓的同花顺

getchar在流结束或出错时返回EOF,EOF!='\n',所以如果没有EOF检查,该语句将在到达流的末尾时无限循环


输入的最后一行是否会换行终止,这一点并不确定。事实上,您可能会争辩说流的最后一行是在流的末尾终止的,因此最后一行永远不会以换行符终止,尽管它可能包含零个字符。

您不会用EOF刷新stdin,代码只是从stdin读取所有字符并丢弃它们,这取决于代码的位置,我指的是上下文。例如,如果使用SCANF读取一个值并输入一个有效值,后面跟着空格,则该代码将从输入缓冲区中删除所有空格。考虑shell从文件输入管道到应用程序的STDIN的场景……为了完整性,你可能想发布c的类型,它应该是int而不是char。你不会用EOF刷新stdin,代码只是从stdin中读取所有字符并丢弃它们,这取决于代码的位置,我指的是上下文。例如,如果使用SCANF读取一个值并输入一个有效值,后面跟着空格,则该代码将从输入缓冲区中删除所有空格。考虑shell将文件从管道输入到应用程序的STDIN的场景……为了完整性,您可能需要张贴应该是int而不是char的C类型。除了我们从一个有真正EOF的文件中通过管道输入的场景之外
ch基本上回答了我的问题,我仍然不明白为什么我们在任何其他场景中需要EOF来实现这样的功能。用户只能在终端中一行的开头调用EOF,因此它不能用于清空缓冲区。@Mcs,用户可能不需要发送EOF,但您的程序应该考虑到它将获得EOF的可能性。@Mcs:这完全取决于终端仿真器;在我的Linux机器上,xterm、Konsole和所有虚拟控制台都很乐意接受第一个Ctrl-D中间行作为stdin flush,下一个仍然与EOF在同一行。谢谢,除了我们从一个有真正EOF的文件中进行输入的场景,这基本上回答了我的问题,我仍然不明白为什么我们在任何其他场景中需要EOF来实现这样的功能。用户只能在终端中一行的开头调用EOF,因此它不能用于清空缓冲区。@Mcs,用户可能不需要发送EOF,但您的程序应该考虑到它将获得EOF的可能性。@Mcs:这完全取决于终端仿真器;在我的Linux机器上,xterm、Konsole和所有虚拟控制台都愉快地接受第一个Ctrl-D中间行作为stdin刷新,而下一个仍然与EOF在同一行上;而c!=EOF&c!='\n′;第二,当我在windows中按下control+z时,除非我写了一个程序说应该发生什么,否则什么都不会发生,为此我需要阅读EOFanyway@Mcs这就是EOF的问题,除非你提出要求,否则它不会出现在你面前。按Ctrl+z键不会发送EOF,它只是告诉控制台将输入流标记为关闭。在这一点上,没有其他东西可以进入流,但是已经存在的字符将保留在那里。因此,如果在按下Ctrl+z之前输入hello,程序读取前三个字符,其他两个字符将保留在缓冲区中,供程序读取。谢谢@dasblinkenlight,我想我将进行更多的尝试和错误,以真正了解发生了什么:好的,这段代码刷新stdin:do c=getchar;而c!=EOF&c!='\n′;第二,当我在windows中按下control+z时,除非我写了一个程序说应该发生什么,否则什么都不会发生,为此我需要阅读EOFanyway@Mcs这就是EOF的问题,除非你提出要求,否则它不会出现在你面前。按Ctrl+z键不会发送EOF,它只是告诉控制台将输入流标记为关闭。在这一点上,没有其他东西可以进入流,但是已经存在的字符将保留在那里。因此,如果在按下Ctrl+z之前输入hello,程序读取前三个字符,其他两个字符将保留在缓冲区中,供程序读取。谢谢@DasbLinkedLight,我想我将进行更多的尝试和错误,以真正了解发生了什么:但为什么用户键入某些内容,然后执行control-z enter,这对我来说毫无意义,用户只能在一行的开头调用EOF,我不明白,也许我还是不明白EOF是怎么回事works@Mcs这是不正确的,终端用户可以在一行的开始调用EOF,你可以在任何时候,在一个单词的中间按下它。dasblinkenlight描述了两种情况,其中程序可能会在stdin上遇到EOF。当一个程序的输出通过管道传输到另一个程序的输入时,就会出现第三个相关的程序。在任何情况下,如果一个程序认为它的输入只会采用它想要的形式,这都是一种糟糕的做法。一个健壮的程序考虑了所有的可能性。感谢@ DasBrink NeXT,这里有很多错误信息,我记得你今天不能在一行中调用EOF,但是为什么用户要输入一些东西,然后做控制-Z输入,这对我来说是没有意义的,无论如何,用户只能在一行的开头调用EOF。我不明白,也许我还是不明白works@Mcs这是不正确的,终端用户可以在一行中调用EOF,您可以在任何时候,在一个单词的中间按下它。@ MCS,DasBrink NeLink描述了两个场景,其中程序可能在STDIN上遇到EOF。当一个程序的输出通过管道传输到另一个程序的输入时,就会出现第三个相关的程序。在任何情况下,如果一个程序认为它的输入只会采用它想要的形式,这都是一种糟糕的做法。一个健壮的程序解释了所有的可能性。感谢@ DasBLink的光,这里有很多错误信息,我记得读到今天你不能调用EOF。