cin和switch的奇怪行为

cin and switch odd behaviour

本文关键字:switch cin      更新时间:2023-10-16

所以我在使用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中的什么?

提前感谢:

在输入choice后,函数newCustomers似乎被一两个游离字符挂起了。这就解释了为什么ignore调用"修复"了这个问题,这也是@TheBuzzSaw在评论中建议的解决方案。

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

cout << "test";

cout << "testn";

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

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

cerr << "testn";

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

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

编辑:我无法对你的帖子发表评论,所以我想我会在这里发布。"悬挂"可能是一个无限循环。如果你正在做像我正在做的事情,并循环以获得输入,但未能清除错误位,cin将不断失败。如果你没有在每次请求输入时定制某个东西,它可能只是静静地坐在那里循环输入收集功能。在所有循环中设置断点,然后使用调试器逐步验证没有任何循环是无限循环。

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

解释:

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

我建议不要使用裸cin>>选项,因为它可能会失败,而且你不会知道。我会将其抽象为一个方法,以获得你想要的正确输入。

我个人保留了一个很小的实用程序库(.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;
}

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

char buffer[64];
cin.getline(buffer, 64);
char choice = buffer[0];
switch (choice)
{
    ...
}

您的cin可能没有被重置,任何多余的字符都被输入到后续的输入请求中。获取更多输入,只处理其第一个字符。