我正在构建一个产品结帐软件,我不断遇到一个奇怪的错误。我有一个中央菜单,可以获得用户输入。函数完成任务后,会将用户返回菜单。但是,对于某些函数,菜单提示符后面的cin.get()会出现错误,并且不会接受给定的第一个命令。以下是相关的代码片段:
主菜单循环:
bool foreverLoopFlag = true;
while (foreverLoopFlag) {
cout << "\nC[heckout], R[eturn], S[tudent], P[roduct], Q[uit]. Choice? ";
cin.get(actionChoice);
std::cin.ignore(std::numeric_limits<streamsize>::max(),'\n');
cout << endl;
actionChoice = toupper(actionChoice);
switch (actionChoice) {
case 'C':
checkoutSoftware(studentMap, productList);
break;
case 'R':
returnSoftware(studentMap, productList);
break;
case 'S':
studentDisplay(studentMap, productList);
break;
case 'P':
productDisplay(studentMap, productList);
break;
case 'Q':
foreverLoopFlag = false;
break;
default:
cout << "Invalid command.\n";
break;
}
}
问题 - 子功能,studentDisplay:
void studentDisplay(map<string, Student> & studentMap, list<Product> & productList) {
string inputCLID;
cout << "Please enter student CLID: ";
cin >> inputCLID;
if (studentMap.find(inputCLID) != studentMap.end()) {
cout << "\nStudent: " << studentMap[inputCLID].name << " (" << inputCLID << ")\n";
cout << "\tBorrowed items: " << endl;
for (list<Student::LentProduct>::iterator it = studentMap[inputCLID].checkedOut.begin();
it != studentMap[inputCLID].checkedOut.end(); it++) {
cout << "\t\tProduct: " << (*it).name;
cout << "\tDue Date: " << (*it).dateDue << endl;
}
} else {
cout << "\nError: CLID not in database.\n";
}
}
有一些压痕被转移到SE,我道歉。这是我遇到的问题的一个例子:
C[heckout], R[eturn], S[tudent], P[roduct], Q[uit]. Choice? s
Please enter student CLID: mrx8394
Student: Mark Xeno (mrx8394)
Borrowed items:
Product: Bluebeard Due Date: 12/14/2013
C[heckout], R[eturn], S[tudent], P[roduct], Q[uit]. Choice? c
Invalid command.
C[heckout], R[eturn], S[tudent], P[roduct], Q[uit]. Choice? q
我尝试在菜单循环的开头放置一个std :: cin.flush(),但这不起作用。我尝试在菜单循环开始时执行std :: cin.ignore(std :: INT_MAX),但这使得菜单从未出现过。我也尝试了一个std :: cin.sync(),但这只是一个无限循环:
C[heckout], R[eturn], S[tudent], P[roduct], Q[uit]. Choice?
Please enter a product to checkout:
Error: No such product.
我不知道从哪里开始。我知道这可能只是我不喜欢的iostream的一些怪癖。任何助理都将不胜感激。
编辑:我没有足够的声誉对特定答案进行upvote或评论(我的所有代表都在Math.SE !!!),所以我在这里发表评论。 @ Igor-tandetnik的解决方案完美无缺。我已经将其他所有内容都移到了getline上,但我认为那个人刚刚离开了。我的谢意成群结队。@qwrrty虽然这可能是愚蠢的,但我有一个规范要见(你不喜欢低级大学课程)。我通常不会要求帮助调试任务,但这是最后一个错误,我对iostream的了解不是那么深,但我知道有人在这里会知道什么是我的流状态。
再次感谢大家,欢呼!
答案 0 :(得分:1)
cin >> inputCLID
读取字符,但不包括第一个空白字符(在您的示例中为换行符)。该字符留在流中。这是cin.get(actionChoice)
后来检索的字符。
答案 1 :(得分:0)
我倾向于认为对于交互式输入,尝试使用stdin和/或cin读取除完整输入行之外的任何内容都是愚蠢的。您的程序有太多方法让您对输入流中的内容感到困惑,并最终处于不可恢复的状态。
至少我会修改程序,说它认为无效的命令,或者不存在的产品:
default:
cout << "Invalid command '" << actionChoice << "'\n";
和
cout << "Error: No such product '" << productChoice << "'\n";
至少你可以了解程序实际用于这些变量的输入。