在调用std :: getline之前检查数据可用性

时间:2010-07-23 11:35:37

标签: c++ iostream

我想从使用std::getline的流中读取一些数据。 在使用std::cin

的示例下方
std::string line;
std::getline( std::cin, line );

这是一个阻塞函数,即如果没有要读取的数据或行,则阻止执行。

您是否知道在调用std::getline之前是否存在检查数据可用性的功能?我不想阻止。

如何检查流缓冲区是否已满足成功调用std::getline的数据?

看起来像下面的代码

if( dataAvailableInStream() )
{
     std::string line;
     std::getline( std::cin, line );
}

7 个答案:

答案 0 :(得分:17)

答案 1 :(得分:8)

答案 2 :(得分:4)

此代码可以帮助您检查stdin中数据的存在而不会阻止:

std::cin.seekg(0, std::cin.end);
int length = std::cin.tellg();
if (length < 0) return; //- no chars available

如果stdin有一些数据 - 请不要忘记将位置设置回到开头。

std::cin.seekg(0, std::cin.beg);

然后,您可以在缓冲区末尾读取包括\0(可以多于一个)的所有数据:

std::vector<char> s(length);
std::cin.read(s.data(), length);

或逐行:

std::string line;
while (std::cin) {
    std::getline(std::cin, line);
    //.....
}

此代码适用于MSVC和gcc(Ubuntu)

答案 3 :(得分:1)

hack可能是在读取之前调用kbhit()。可能不便携,充满危险......

#include <conio.h>
#include <iostream>

using namespace std;


char buffer[128];

if (kbhit())
{
     cin.getline(buffer, sizeof(buffer));
}

答案 4 :(得分:0)

答案 5 :(得分:0)

答案 6 :(得分:-3)

std :: iostream提供了一个peek函数,它返回流中的下一个字符而不删除它。所以你可以做类似以下的事情(完全没有经过测试)。

bool dataAvailableInStream( std::iostream &stream )
{
  return stream.peek() != std::iostream::traits_type::eof();
}

修改

正如rubenvb指出的,std::cin按设计阻止。因此,上面的代码会让您超过getline阻止,但不会cin

修改编辑

正如查尔斯在下面指出的那样,peek会阻止,如果没有数据可用。因此,这不提供完整的解决方案。它会阻止您在getline上阻止,但不会阻止整体阻止。