C++使用cin.get来获取一个字符,但在遇到EOF时不会结束while循环

C++ use cin.get to get a character, but not end the while loop when encounter the EOF

本文关键字:EOF 遇到 循环 while 结束 字符 get cin 使用 获取 一个      更新时间:2023-10-16

下面是我的代码,我想从stdin中读取字符,并在遇到EOF(ctrl-z)时结束。

#include<iostream>
#include<fstream>
#include<stdio.h>
#include<string>
using namespace std;
int main()
{
string article ;    
char nextChar;
while( cin.get(nextChar) ) {
if( cin.eof() ) break ;
article.append(1, nextChar) ;
}
cout << article ;
system("pause") ;
}

我测试这样的输入:

I am a student.<ctrl-z>

然后我按下回车键,但它没有停止。

当我键入另一个[ctrl-z],然后按neter。

它只能退出while循环。

为什么第一个[ctrl-z]没有发出eof条件的信号?

下面的解释稍微简化了一些。

这是操作系统的一个功能。这就是操作系统的工作方式。

文件结尾实际上是返回0的底层read()系统调用。文件结尾不是CTRL-Z。操作系统将对CTRL-Z进行解释,以刷新其交互式密钥缓冲区,并使进程read()包含其内容。

当您输入一个终端时,直到按下Enter,该过程实际上不会读取任何内容。此时,read()系统调用完成,并返回已读取的所有内容。一般来说,在按下Enter之前,您可以退格并编辑您键入的内容,并且您的程序没有指示您已经编辑了任何内容,所有这些read()s都是按下Enter之后的行的最终内容。

如果您键入某些内容,然后按CTRL-Z,则程序键入的输入也是read(),就好像它是在中键入的一样

只有当未键入任何内容,并且按下了CTRL-Z时,底层的read()系统调用才会返回0,因为首先没有键入任何内容;这被解释为文件结束指示。但是,如果某个内容首先被输入,则需要输入两次CTRL-Z,一次输入到输入的read(),然后清除输入缓冲区,第二次输入CTRL-Z,以使read()为0。

顺便说一下,您的代码有一个无害的错误。如果cin.get()成功,则cin.eof()永远不可能为真。