cin并切换奇怪的行为

时间:2012-08-23 15:13:50

标签: c++ switch-statement cin

因此,在使用cinswitch语句时遇到了一些问题。 首先,程序会提示int

cout << "How many registers would you like to use?: ";
cin >> kassor;

稍后,要求用户做出选择:

    cout << endl << "Press \"S\" to run the queue simulator and/or make a timestep." << endl;
    cout << "Press \"Q\" to quit." << endl << endl;
    cout << "Choice: ";
    cin >> choice;

    switch (choice)
    {
        case 's':
        case 'S':
        {
            cout << "test";
            nya = newCustomers();
            break;
        }
        case 'q':
        case 'Q':
        {
            return 0;
        }
    }

这里,'q'选项工作正常,但's'选项没有。它“挂起”,好像还在等待输入。我尝试了各种cin.ignore()等等,但无济于事。

令我困惑的是

switch (choice)
{
    case 's':
    case 'S':
    {
        cout << "test";
        nya = newCustomers();
        break;

什么都不给,但以下内容:

switch (choice)
    {
        case 's':
        case 'S':
        {
            cout << "test";
            cin.ignore(1024, '\n');
            nya = newCustomers();
            break;

输出'测试'。

我的主要问题是:问题是cin还是case: s中的问题?

提前感谢:

3 个答案:

答案 0 :(得分:1)

在输入newCustomers之后,看起来函数choice挂起了一两个迷路字符。这可以解释为什么ignore调用“修复”了问题,这是@TheBuzzSaw在评论中建议的解决方案。

要更清楚地看到这一点,请更改

cout << "test";

cout << "test\n";

cout << "test" << std::endl;

在某些系统上,控制台是行缓冲的,因此在程序写入换行符之前,您将看不到任何输出。插入endl会刷新输出缓冲区,因此即使后续代码挂起,您也应该看到该消息。或者将其更改为:

cerr << "test\n";

cerr更积极地刷新缓冲区,正是因为它用于你不想错过的错误输出。

答案 1 :(得分:0)

简答: 我相信cin在某个地方失败,或者它是意外行为的原因 如果没有更多代码,我无法确定它。

修改:我无法在您的帖子上发表评论,所以我想我会在这里发帖。 “悬挂”可能是一个无限循环。如果你正在做我正在做的事情并循环以获得输入并且无法清除错误位cin将不断失败。如果你不是每次要求输入时都没有什么东西,它可能只是静静地坐在那里循环通过输入收集功能。在所有循环中放置断点并使用调试器逐步执行以验证没有循环是无限循环。

尝试添加std :: cin.clear();在第二个测试用例中的.ignore()之前。看看是否会阻止你的悬挂。

<强>解释

cin可能会失败。这可能会导致奇怪的行为。它失败的一种常见方式是,如果您正在读取整数并获得字符输入。一旦cin失败,它就会设置一个失败位,从那时起,cin的行为就像你期望的那样。

我建议不要使用裸露的cin&gt;&gt;选择,因为它可能会失败,你不会知道它。我会把它抽象出一个能得到你想要的正确输入的方法。

我个人保留一个小实用程序库(.h)和.cpp,以包含在我使用我已编码的常用功能的项目中。

我有一个readIntBetween()函数,它接受2个整数,并从标准输入读取这两个数字之间的整数。如果用户没有提供正确的输入(整数超出或超出界限,或包含字符的输入),我请他们重新输入输入。

在这个函数中,我确保在检测到故障时清除失败位,并忽略200个字符以“冲洗”它。

这是我的readIntBetween函数的代码。我希望它可以帮助您诊断错误并修复它:

int readIntBetween(int lower, int upper, std::string prompt)
{
    bool goodVal = false;
    int value = -1;
    do
    {
        std::cout << prompt ;
        std::cin >> value;

        if ( value >= lower && value <= upper)//check to make sure the value is in between upper and lower
            goodVal = true;
        else
        {
            if(std::cin.fail())
            {
                std::cout << "\tError - invalid format for integer number" << std::endl;

                //clear all status bit including fail bit
                std::cin.clear();

                //flush input buffer to discard invalid input
                std::cin.ignore(1000, '\n');

            }
            else
            std::cout << "Value is not valid, must be between " << lower<<" and "<<upper<<"."<<std::endl;
        }



    }while(!goodVal);
    return value;
}

答案 2 :(得分:0)

如果您在循环中使用cin,我建议采用不同的方法。

char buffer[64];
cin.getline(buffer, 64);

char choice = buffer[0];

switch (choice)
{
    ...
}

您的cin可能未被重置,并且任何无关的字符都被输入到后续的输入请求中。获取更多输入并仅处理其第一个字符。