使用cin两次的问题

时间:2010-03-26 17:30:12

标签: c++ cin

以下是代码:

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

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

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

然而,我仍然不明白,为什么在第一次通话后'\ n'留在那里?什么是梦想&amp;运营商GT;&GT;真的吗?

6 个答案:

答案 0 :(得分:7)

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

您也可以在\n之后立即致电cin.get()来移除cin>>str。然而,有许多不同的方法可以为这个特定的I / O猫换肤。 (或许本身就是个好问题?)

答案 1 :(得分:2)

正如其他人所说,问题在于换行是从第一次提取开始的。我做的一个解决方案是丢弃流中的所有左侧字符:

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

答案 2 :(得分: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的方法避免了必须考虑输入的行缓冲,清除输入等。如果您使用&gt;&gt;直接读取内容,如果用户点击输入而不是输入,则输入不会终止需要什么,但继续直到输入一个令牌(通常不需要这种行为)。

答案 3 :(得分:1)

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

答案 4 :(得分:0)

Good writeup that explains some of the reasons why您遇到此问题,主要是由于输入类型的行为以及您正在混合它们

答案 5 :(得分: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' );

更灵活。

P.S。如果max()函数出现错误,例如“标识符预期”,则可能是由某些标题中定义的max宏引起的(例如,Microsoft);这可以通过使用

来解决
 #undef max