有没有什么方法可以调用 getline()
并且在没有输入的情况下不阻塞等待?
我有以下代码:
while(true){
if(recv(sd, tBuffer, sizeof(tBuffer), MSG_PEEK | MSG_DONTWAIT) > 0) break;
getline(cin,send);
}
我想等待输入,但如果我在 sd
套接字上收到一些数据,我想停止等待数据并退出 while
。我现在的代码只是停留在 getline()
的第一次迭代中。我想评估 getline()
,如果没有可用的输入,返回 if
。
这可能吗?
PS:我尝试使用 cin.peek()
,但它也会阻止输入。
最佳答案
你应该能够通过在标准输入、文件描述符 0 上设置非阻塞模式来做到这一点:
int flags = fcntl(0, F_GETFL, 0);
fcntl(0, F_SETFL, flags | O_NONBLOCK);
现在,如果没有可用的输入,底层的 read()
系统调用将返回 0,并且 std::cin
会认为这是文件结尾,并在 std::cin
上设置 eof()
。
当您希望再次从标准输入读取时,只需clear()
流的状态即可。
这里唯一复杂的因素是,这使得很难在 std::cin
上检测到真正的文件结束条件。当标准输入是交互式终端时问题不大;但如果标准输入可以是一个文件,这将是一个问题。
在这种情况下,您唯一现实的选择是完全放弃 std::cin
,将非阻塞模式置于文件描述符 0、poll()
或 select()
它,确定什么时候有东西要读,然后 read()
它。
尽管您也可以将 poll()
或 select()
与 std::cin
一起使用,但这会变得复杂,因为您需要明确检查 std::cin
的 streambuf
中是否已经缓冲了任何内容,因为这显然会抢占任何类型的 poll()
或 select()
检查;但是通过尝试从 std::cin
中读取某些内容,您仍然冒着读取缓冲数据的风险,然后尝试从现在的底层文件描述符中 read()
在非阻塞模式下,这会导致伪造的文件结束条件。
总而言之:您需要投入一些额外的时间来阅读和理解文件流和流缓冲区的工作原理;以及文件描述符实际如何工作,以及非阻塞模式如何工作;为了找出您需要使用的正确逻辑。
哦,如果你坚持使用 std::cin
和 getline()
的非阻塞路线,你将没有简单的方法来确定是否getline()
返回的字符串结束,因为 getline()
实际上从标准输入读取了一个换行符,或者它达到了过早的假文件结束条件而不是整行实际上已经读取了输入。
因此,使用非阻塞模式和 std::cin
,您将不得不使用 read()
,而不是 getline ()
。
关于c++ - 如何在不阻塞输入的情况下使用 getline?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41558908/