繁体   English   中英

需要帮助修复奇怪的cin行为

[英]Need help fixing strange cin behavior

我正在构建一个产品结帐软件,并且不断遇到奇怪的错误。 我有一个中央菜单,可以获取用户输入。 功能完成其任务后,它将使用户返回菜单。 但是,对于某些功能,我在菜单提示后输入的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的一些怪癖。 任何助手将不胜感激。

编辑:我没有足够的声誉来赞扬或评论特定的答案(我的所有代表都在Math.SE上!!!),所以我将在这里发表评论。 @ Igor-tandetnik的解决方案运行完美。 我已经将其他所有内容移到了一条Getline,但我想那家伙只是被拖进了洗牌场。 我的谢意成群结队。

@qwrrty虽然很愚蠢,但我有一个要满足的规范(您不只是喜欢低级的大学课程)。 我通常不需要寻求调试任务的帮助,但这是最后一个错误,我对iostream的了解并不深,但是我知道这里的人会知道是什么使我的流状态出错。

再次感谢你们,加油!

cin >> inputCLID读取的字符最多但不包括第一个空格字符(在您的示例中为换行符)。 该角色留在信息流中。 cin.get(actionChoice)之后检索的是该字符。

我倾向于认为对于交互式输入,尝试使用stdin和/或cin读取全行输入以外的任何内容都是愚蠢的。 对于您的程序,有太多的方法会混淆输入流中仍然存在的内容,并最终导致无法恢复的状态。

至少,我会修改程序说它认为是无效的,或不存在的产品是什么命令:

    default:
        cout << "Invalid command '" << actionChoice << "'\n";

    cout << "Error: No such product '" << productChoice << "'\n";

这样,至少您可以了解程序实际上为这些变量使用的输入。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM