I wanted the user to input 1, 2, 3, or 4, and ONLY those numbers. I do not want: 5, 79, 4rf, 1XXXXX, 2!, abc 1234, etc.
If I use 'cin >> ', then it would cut off the input to something like '2!' to the 2 and leave the '!' in for the next input, so getline() is preferable. The code I have listed technically works, but leaves an extra line of input when I ask again for another input after the user put in a invalid one.
Thank you for the help.
bool check = true;
string input;
int choice;
cout << "Please enter 1, 2, 3, or 4:" << endl;
getline(cin, input);
do
{
check = true;
if (input.length() != 1 || !isdigit(input[0]))
{
cout << "error, enter a valid input" << endl;
check = false;
cin.clear();
cin.ignore(INT_MAX, '\n');
getline(cin, input);
}
else
{
choice = stoi(input);
if (!(choice == 1 || choice == 2 || choice == 3 || choice == 4))
{
cout << "error, enter a valid input" << endl;
check = false;
cin.clear();
cin.ignore(INT_MAX, '\n');
getline(cin, input);
}
else
{
check = true;
}
}
} while (check == false);
getline(cin, input);
consumes an entire line or fails, and failure for getline
on cin
is pretty much the end of cin
. If you got data at all, you got the whole line. There is nothing for cin.ignore(INT_MAX, '\\n');
to ignore, so the user winds up having to hit enter again before they can get to the getline(cin, input);
retry.
Keeping your basic stricture, I'd clean it up to something more like
bool check = false; // assume failure
string input;
int choice;
cout << "Please enter 1, 2, 3, or 4:" << endl;
while (!check)
{
if (getline(cin, input)) // test that we got something
{
if (input.length() != 1 || !isdigit(input[0]))
{
cout << "error, enter a valid input" << endl;
// don't need to do anything else here
}
else
{
choice = input[0] - '0'; // easier conversion
if (!(choice == 1 || choice == 2 || choice == 3 || choice == 4))
{
cout << "error, enter a valid input" << endl;
// don't need to do anything else here
}
else
{
check = true; // all done
}
}
}
else
{
// to be honest there isn't much you can do here. You can clear and
// ignore, but it's hard to make unformatted input fail and still
// have a viable console. Maybe you should throw an exception, but
// for a simple program I'm all for giving up.
cerr << "Aaaaaaahhhhrrrg!\n";
exit(-1);
}
}
I'm assuming failure because I only have one place I need to set the check
flag: On success! This makes it a bit easier to pick this code up and put it in a function so you can reuse it more easily. Make the loop go forever and replace check = true;
with return choice;
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.