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

Why does this while loop repeat after every character of an input?

本文关键字:字符 之后 循环 while 输入 为什么      更新时间:2023-10-16
我写了一些代码来检查用户是否使用while循环输入了正确类型的输入。问题是,在你输入的每一个错误字符之后,它都会再次循环。

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

代码如下:

#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();
}
}
}

循环之所以发生,是因为在提取一个字符后,cin缓冲区中还有剩余字符。因此,如果您键入querty<enter>,在它处理q之后,它仍有uertyn要处理。然后它循环,因为它没有找到满足条件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';
}

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

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

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

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

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