我正在尝试从控制台获取一些用户输入参数,两个字符串,两个整数和一个double。我试图使用的相关代码是:
#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);
但是,在运行程序时,代码不会等待输入第一个inputString,代码在第二次getline()调用之前不会停止。因此控制台输出如下所示:
标题:类别:
将光标显示在类别之后。如果我现在输入,程序然后跳转到年份输入,不允许我输入多个字符串。这里发生了什么?
答案 0 :(得分:20)
问题是你使用运算符&gt;&gt;混合调用getline()。
请记住,运营商&gt;&gt;忽略前导空格,因此将正确地跨越线边界继续。但是在成功检索到输入后停止读取,因此不会吞下尾随'\ n'字符。因此,如果您在&gt;&gt;之后使用getline()除非你小心(首先删除未读取的'\ n'字符),否则你通常会得到错误的东西。
诀窍是不使用这两种类型的输入。选择合适的一个并坚持下去。
如果它是所有数字(或与运算符&gt;&gt;匹配的对象),那么只需使用运算符&gt;&gt; (注意字符串是唯一与输入/输出不对称的基本类型(即不能很好地播放)。)
如果输入包含字符串或需要getline()的东西的组合,那么只使用getline()并解析字符串中的数字。
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);
答案 1 :(得分:12)
您需要刷新输入缓冲区。可以使用cin.clear(); cin.sync();
完成。
答案 2 :(得分:8)
您可以使用
cin.ignore();
或@kernald提到使用
cin.clear();
cin.sync();
使用getline()之前
答案 3 :(得分:3)
如上所述使用cin.clear()
和使用正确的错误处理:
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);
答案 4 :(得分:1)
如果用户在 getline 之前的 cin 中的\ n之前输入空格,则仅 ignore 本身是不够的,因此您必须使用此代码,而不是单独使用 ignore()。例如, 12345 \ t \ n 将不再起作用。 所有未处理的字符都必须忽略。
#include <limits>
cin.ignore(numeric_limits<streamsize>::max(), '\n');
在 cin 和 getline 之间使用它。
答案 5 :(得分:0)
将getline()与输入流混合通常是一件坏事。理论上可以手动处理使用流留下的脏缓冲区,但这绝对是一种不必要的痛苦。
最好使用控制台库来获取输入,这样可以为您提取脏工作。
看看TinyCon。您可以使用静态方法tinyConsole :: getLine()来代替您的getline和stream调用,并且您可以根据需要多次使用它。
您可以在此处找到相关信息: https://sourceforge.net/projects/tinycon/
答案 6 :(得分:0)
cin.sync(); 用它代替cin.ignore( 效果最好。
答案 7 :(得分:0)
还可以与ws
一起使用。使用getline(cin >> ws, inputString)
命令读取数据后,您可以使用cin
)来吃空格或换行符。