为什么while循环在输入的每个字符后重复?

时间:2017-02-09 02:46:28

标签: c++ function loops while-loop

我编写了一些代码,用于检查用户是否使用while循环输入了正确的输入类型。问题是,在输入每个错误字符后,它会再次重新循环。

但是当你输入多个字符时,它会一次又一次地循环相同的cout语句。例如,如果我键入" qwerty",当我只希望它运行一次时,它会输出那些 cout`语句6次。

代码如下:

#include <iostream>
using namespace std;
int main(){
    // Declare the variables
    int choice = 0;
    bool valid = false;

    while(!valid){

    valid = true;
    //Ask the user for their choice
    cout << "Which function would you like to use? \n";
    cout << "1) Average Function \n";
    cout << "2) Mean Absolute Deviation Function \n";
    cout << "3) Number Sorting Function \n";
    cout << "4) Median Function \n";
    cout << "5) All of the above \n";
    cout << "6) Calculator Function \n";
    cout << "Your choice: ";
    cin >> choice;

        if(cin.fail() || choice > 6 || choice < 1){
            cout << "ERROR, PLEASE ENTER ONLY VALID SYMBOLS \n";
            cout << "--------------------- \n";
            valid = false;
            cin.clear();
            cin.ignore();
        }

    }
}

2 个答案:

答案 0 :(得分:2)

发生循环是因为在提取一个字符后,cin缓冲区中仍有字符。因此,如果您键入querty<enter>,则在处理q之后,它仍然需要处理uerty\n。然后循环,因为它没有找到满足条件choice > 6 || choice < 1的输入值并尝试其他字符提取。它可以执行6次,直到缓冲区为空并且设置了cin.fail()标志。

另一种方法是以字符串形式读取整行,并从该行中提取整数。

#include <iostream>
#include <sstream>
#include <string>
using namespace std;

int displayUserInstructions(){

    string line;

    while(true){

        cout << "Which function would you like to use? \n";
        cout << "1) Average Function \n";
        cout << "2) Mean Absolute Deviation Function \n";
        cout << "3) Number Sorting Function \n";
        cout << "4) Median Function \n";
        cout << "5) All of the above \n";
        cout << "6) Calculator Function \n";
        cout << "Your choice: ";

        if(getline(cin, line)){

            stringstream ss(line);
            int choice;

            if(ss >> choice && (choice >= 1 && choice <= 6)){

                return choice;
            }

            cout << "ERROR, PLEASE ENTER ONLY VALID SYMBOLS \n";
            cout << "--------------------- \n";
        }
    }
}

int main()
{
    int choice = displayUserInstructions();
    cout << "You made the valid choice of " << choice << '\n';
}

答案 1 :(得分:2)

当您输入“qwerty”时,表示输入缓冲区中有六个字符等待读取。您的代码尝试使用cin >> choice读取整数,但发现它不是有效的整数,因此会输出错误,清除流状态,丢弃一个字符,然后重新启动循环。然后它读取下一个字符'w',它不是一个有效的整数,因此它会输出错误并丢弃一个字符,然后重新启动。

您可以通过将所有内容丢弃到下一个换行符来解决此问题:

cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

这会将所有字符丢弃到行尾,而不是试图从错误的输入中继续读取整数。

或者,您可以立即读取整行并尝试从中提取整数(如Paul Rooney的回答所示)。两者都应该同样有效,尽管取决于您在计划中下一步要做什么,一个或其他解决方案可能更灵活。一个解决方案读取整行然后尝试从中提取整数(并忽略该行的其余部分)。另一个解决方案尝试首先提取一个整数并在出错时丢弃该行(如果没有错误,则该行的其余部分仍然可读)。