【问题标题】:Why does this while loop repeat after every character of an input?为什么这个while循环在输入的每个字符之后重复?
【发布时间】:2017-06-26 21:52:14
【问题描述】:

我编写了一些代码来检查用户是否使用 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();
        }

    }
}

【问题讨论】:

  • 我不确定如何使用调试器:/
  • @PeteMcGreete 在没有调试技能的情况下,只需在其中粘贴几个couts 肯定会帮助您了解程序执行某些阶段的控制流和变量值。绝对值得学习使用调试器,因为它更快,而且您不必返回代码,撕掉cout 语句。
  • 但是当您输入多个字符时,它会一次又一次地循环相同的cout 语句。例如,如果我输入 qwerty,当我只希望它运行一次时,它会输出那些 cout 语句 6 次。
  • @PeteMcGreete,你应该在问题中这么说。这是您所要求的关键部分!我已将其添加到问题中。
  • 另外,请显示完整代码。如果没有main(),它将只添加 5-6 行来使其成为一个完整的程序而不仅仅是一个函数。见stackoverflow.com/help/mcve

标签: c++ function loops while-loop


【解决方案1】:

发生循环是因为在提取一个字符后,cin 缓冲区中仍有字符。因此,如果您键入querty&lt;enter&gt;,在它处理q 之后,它仍然有uerty\n 需要处理。然后它循环,因为它没有找到满足您的条件choice &gt; 6 || choice &lt; 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';
}

【讨论】:

    【解决方案2】:

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2018-12-02
      • 1970-01-01
      • 2011-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多