有没有什么方法可以调用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()
,但它也阻止了输入。
4条答案
按热度按时间y3bcpkx11#
您应该能够通过在标准输入上设置非阻塞模式来做到这一点,文件描述符0:
现在,如果没有可用的输入,底层的
read()
系统调用将返回0,std::cin
将认为这是文件的结尾,并在std::cin
上设置eof()
。当你想再次从标准输入中读取数据时,只需要
clear()
流的状态。这里唯一的复杂因素是,这使得在
std::cin
上检测真实的的文件结束条件变得困难。当标准输入是一个交互式终端时,这不是什么大问题;但如果标准输入可以是一个文件,这将是一个问题。在这种情况下,您唯一现实的选择是完全放弃
std::cin
,在文件描述符0,poll()
或select()
it上设置非阻塞模式,以确定何时有内容要读取,然后read()
它。虽然您也可以将
poll()
或select()
与std::cin
一起使用,但这将变得复杂,因为您需要显式地检查std::cin
的streambuf
中是否已经缓冲了任何内容,因为这显然会抢占任何类型的poll()
或select()
检查;但是如果试图从std::cin
中读取一些内容,您仍然会面临阅读缓冲数据的风险,然后尝试从现在处于非阻塞模式的底层文件描述符中读取read()
,这会导致虚假的文件结束条件。总结如下:你需要投入一些额外的时间来阅读和理解文件流和流缓冲区是如何工作的;以及文件描述符实际上如何工作,以及非阻塞模式如何工作;为了找出正确的逻辑,你需要使用。
哦,如果你坚持使用
std::cin
和getline()
的非阻塞路由,你将没有简单的方法来确定getline()
返回的字符串是否结束,因为getline()
实际上从标准输入中读取了一个换行符,或者它达到了一个过早的文件伪结束条件,而不是整个输入行实际上已经被读取。因此,使用非阻塞模式和
std::cin
,您将被迫使用read()
,而不是getline()
。dwbf0jvd2#
istream::getsome()方法可用于执行非阻断读取。您可以使用它来构建一个std::getline的非阻塞等价物。
此函数的工作原理与原始
std::getline()
函数相同,只是它总是立即返回。我把它放在my gists上,因为它偶尔会派上用场。v2g6jxz63#
我使用select()检索stdin文件描述符的状态。这在Ubuntu和嵌入式Linux板上工作。如果stdin仍然没有收到来自用户的回车键,select将等待一段时间,并报告stdin没有准备好。stopReading可以停止监视stdin并继续其他东西。您可以根据需要对其进行编辑。它可能不适用于特殊的输入tty's。
7cwmlq894#
我试图在我自己的项目中使用@PeteBlackerThe3rd的答案。不幸的是,我只能在运行
std::ios_base::sync_with_stdio(false)
prior时才能让它工作。所以我尝试了我自己的版本,它也是线程安全的,以防多个线程从多个源阅读。调用的函数示例: