当多次调用时,c ++ getline()不会等待来自控制台的input

我试图从控制台,两个string,两个整数和一个双重获得一些用户input参数。 我试图使用的相关代码是这样的:

#include <string> #include <iostream> using namespace std; // ... string inputString; unsigned int inputUInt; double inputDouble; // ... cout << "Title: "; getline(cin, inputString); tempDVD.setTitle(inputString); cout << "Category: "; getline(cin, inputString); tempDVD.setCategory(inputString); cout << "Duration (minutes): "; cin >> inputUInt; tempDVD.setDuration(inputUInt); cout << "Year: "; cin >> inputUInt; tempDVD.setYear(inputUInt); cout << "Price: $"; cin >> inputDouble; tempDVD.setPrice(inputDouble); 

但是,运行程序时,不要等待input第一个inputString,代码不会停止,直到第二次getline()调用。 因此,控制台输出如下所示:

标题:类别:

光标出现在类别后面。 如果我现在input,程序然后跳转到年input,不允许我input多个string。 这里发生了什么?

问题是你正在使用操作符>>将getline()的调用混合起来。

请记住,运算符>>忽略前导空白,因此将正确地跨越行边界继续。 但是,在成功检索input后停止读取,因此不会吞下结尾的'\ n'字符。 因此,如果在>>之后使用getline(),通常会得到错误的东西,除非您非常小心(先删除未读取的\ n字符)。

诀窍是不要使用这两种types的input。 select适当的一个,坚持下去。

如果是全部的数字(或者对象和运算符>>都很好),那么就使用运算符>>(注意string是唯一与input/输出不对称的基本types(即不能很好地运行))。

如果input包含string或需要getline()的东西的组合,那么只能使用getline()并将string中的数字parsing出来。

 std::getline(std::cin, line); std::stringstream linestream(line); int value; linestream >> value; // Or if you have boost: std::getline(std::cin, line); int value = boost::lexical_cast<int>(line); 

您需要刷新input缓冲区。 可以用cin.clear(); cin.sync();来完成cin.clear(); cin.sync(); cin.clear(); cin.sync();

您可以使用

 cin.ignore(); 

或者像@kernald提到的那样使用

 cin.clear(); cin.sync(); 

在使用getline()之前

如前所述使用cin.clear() 使用适当的error handling:

  cin.clear(); cin.sync(); cout << "Title: "; if (!getline(cin, inputString)) exit 255; tempDVD.setTitle(inputString); cout << "Category: "; if (!getline(cin, inputString)) exit 255; tempDVD.setCategory(inputString); cout << "Duration (minutes): "; if (!(cin >> inputUInt)) exit 255; tempDVD.setDuration(inputUInt); cout << "Year: "; if (!(cin >> inputUInt)) exit 255; tempDVD.setYear(inputUInt); cout << "Price: $"; if (!(cin >> inputDouble)) exit 255; tempDVD.setPrice(inputDouble); 

将getline()与inputstream混合在一起通常是一件坏事。 理论上可以手动处理使用stream留下的脏缓冲区,但这是一个不必要的痛苦,应该避免。

你最好用一个控制台库来抓取你的input,这样就可以为你抽象肮脏的工作。

看看TinyCon。 你可以使用静态方法tinyConsole :: getLine()来代替你的getline和stream调用,你可以多次使用它。

你可以在这里find信息: https : //sourceforge.net/projects/tinycon/