Reputation: 39
I wrote some code that checks if the user has entered the correct type of input using a while loop. The problem is that after every wrong character you type in, it re-loops again.
But when you enter multiple characters it loops the same cout
statements again and again. For instance if I typed "qwerty", it would output those
cout` statements 6 times when I only want it to run once.
The code is below:
#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();
}
}
}
Upvotes: 3
Views: 1259
Reputation: 21619
The looping occurs because you have characters left in your cin
buffer after you extract one. So if you type querty<enter>
, after it processes q
it still has uerty\n
to process. It then loops, because it didn't find an input value that satisfies your condition choice > 6 || choice < 1
and attempts an other char extraction. It's able to do this 6 times until the buffer is empty and the cin.fail()
flag is set.
An alternative approach is to read the whole line in as a string and extract an integer from the line.
#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';
}
Upvotes: 4
Reputation: 171383
When you enter "qwerty" that means there are six characters in the input buffer waiting to be read. Your code tries to read an integer using cin >> choice
, but finds it isn't a valid integer, and so prints an error, clears the stream state, discards one character, and restarts the loop. Then it reads the next character, 'w'
, which isn't a valid integer, so it prints an errors and discards one character, and restarts.
You can solve this by discarding everything up to the next newline character:
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
That will throw away all the characters up to the end of the line, instead of trying to keep reading integers from bad input.
Alternatively, you could read in a whole line at once and try to extract an integer from it (as shown in Paul Rooney's answer). Both should work equally well, although depending what you want to do next in the program, one or other solution might be more flexible. One solution reads a whole line then tries to extract an integer from it (and ignores the rest of the line). The other solution tries to extract an integer first and discards the line on error (and if there's no error, leaves the rest of the line still readable).
Upvotes: 2