10

这是代码:

string str;
cin>>str;
cout<<"first input:"<<str<<endl;
getline(cin, str);
cout<<"line input:"<<str<<endl;

结果是 getline 永远不会因用户输入而暂停,因此第二个输出始终为空。

在花了一些时间之后,我意识到在第一次调用“cin>>str”之后,似乎'\n'仍然存储在cin中(使用cin.peek()检查),它立即结束了getline。解决方案将在第一个用法和第二个用法之间再添加一行: cin.ignore(numeric_limits::max(), '\n');

但是,我仍然不明白,为什么在第一次调用后留下'\n'?istream& operator>> 到底是做什么的?

4

6 回答 6

7

按照为 定义的方式,将\n留在输入流中。填充输入流中的字符,直到找到空白字符(在本例中),此时填充停止,空白现在是输入流中的下一个字符。operator>>std::stringstd::string\n

您也可以通过在 之后立即\n调用来删除。然而,有很多很多不同的方法可以给这个特定的 I/O 猫蒙皮。(也许本身就是一个好问题?)cin.get()cin>>str

于 2010-03-26T17:34:19.890 回答
2

默认情况下,流插入运算符会一直读取,直到看到空白为止。在看到空格、制表符、换行符等之前,您的第一个调用不会返回。然后需要消耗下一个字符,以便您可以进入下一个字符。

于 2010-03-26T17:34:05.290 回答
2

正如其他人所说,问题是第一次提取时留下了换行符。我做的一种解决方案是丢弃流中的所有左侧字符:

std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
于 2010-03-26T17:41:31.497 回答
2

我通常建议只从 std::cin 进行面向行的输入。因此,您的代码可能如下所示:

string str;
int val;
// Read an entire line and parse an integer from it
{
    string line;
    getline(cin, line);
    istringstream iss(line);
    iss >> val;
}
cout<<"first input:"<<val<<endl;
getline(cin, str);
cout<<"line input:"<<str<<endl;

一定要添加错误检查。

getline-only 方法避免了必须考虑输入的行缓冲、清除输入等。如果您使用 >> 直接读取某些内容,如果用户按 Enter 键而不是输入所需的内容,则输入不会终止,但是而是继续直到输入令牌(通常不需要这种行为)。

于 2010-03-26T17:58:10.647 回答
0

很好的文章,解释了您遇到此问题的一些原因,主要是由于输入类型的行为以及您正在混合它们

于 2010-03-26T17:38:54.467 回答
0

也在寻找最合适的解决方案。此运算符的实施可能会产生问题。读取整行并不总是可以接受的,或者不在一个输入行中混合不同的类型。

为了解决这个问题,当您想从中读取一些数据cin,并且不知道在上次输入操作后是否正确提取了空格时,您可以这样做:

std::string str;
std::cin >> std::ws >> str;

但是你不能用它来清除 cin 的最后一次输入操作后的尾随换行符,以免影响新输入,因为std::ws会消耗所有空格并且在第一个非 ws 字符或EOF将被找到之前不会返回控制,所以按 enter 将未完成输入过程。在这种情况下应该使用

 std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );

哪个更灵活。

PS 如果出现max()“预期标识符”等功能错误,可能是由max某些标头中定义的宏(例如,Microsoft)引起的;这可以通过使用来解决

 #undef max
于 2016-08-08T23:22:26.617 回答