#include <iostream>
int main(int, char **)
{
using namespace std;
int days;
cout<<"How many days did you work this month? ";
cin>>days;
while(!(cin>>days) || (days<1) || (days>31)){
if(!(cin>>days)){
cout<<"Number of days should be... well, a number. Please re-enter: ";
cin.clear();
cin.ignore(100,'\n');
}
else if(days<1 || days>31){
cout<<"Number of days should be between 1 and 31. Please re-enter:";
cin>>days;
}
}
return 0;
}
This is supposed to validate user input:
The first condition is there to avoid an infinite loop when you ask for an int and the user enters a char/string. This part works just fine, it keeps asking for input until I enter a number, and then proceeds to execute the next part of the program (not shown here).
the number of days should be between 1 and 30. If I enter a number - any number, inside or outside the range - the program will not do anything AT ALL. Won't even show the error message.
I can make it work if I use two separate loops, one to validate !(cin>>days)
and another for (days<1) || (days>31)
. I don't know what it is that I'm doing wrong here.
CodePudding user response:
your problem is that you are reading cin input 3 times before you do anything
int days;
cout<<"How many days did you work this month? ";
cin>>days; <<<<<==== 1
while(!(cin>>days) <<<<<<<=====2|| (days<1) || (days>31)){
if(!(cin>>days)){ <<<<<<=== 3
cout<<"Number of days should be... well, a number. Please re-enter: ";
cin.clear();
cin.ignore(100,'\n');
}
else if(days<1 || days>31){
cout<<"Number of days should be between 1 and 31. Please re-enter:";
cin>>days;
}
}
if you want to test if there was an input error just do !cin
ie
int days;
cout<<"How many days did you work this month? ";
cin>>days;
while(!(cin) || (days<1) || (days>31)){
if(!(cin)){
cout<<"Number of days should be... well, a number. Please re-enter: ";
cin.clear();
cin.ignore(100,'\n');
cin >> days;
}
else if(days<1 || days>31){
cout<<"Number of days should be between 1 and 31. Please re-enter:";
cin>>days;
}
}
CodePudding user response:
You are using three sequential calls of cin>>days
cin>>days;
while(!(cin>>days) || (days<1) || (days>31)){
if(!(cin>>days)){
//...
or
while(!(cin>>days) || (days<1) || (days>31)){
if(!(cin>>days)){
//...
}
else if(days<1 || days>31){
//...
cin>>days;
}
}
That just does not make any sense.
The code can look the following way, for example:
int days;
bool failure;
cout<<"How many days did you work this month? ";
while( ( failure = !(cin>>days) ) || (days<1) || (days>31)){
if( failure ){
cout<<"Number of days should be... well, a number. Please re-enter: ";
cin.clear();
cin.ignore(100,'\n');
}
else if(days<1 || days>31){
cout<<"Number of days should be between 1 and 31. Please re-enter:";
}
}
CodePudding user response:
You are calling cin >> days
too many times.
You are prompting the user for input and then reading in days
before entering the loop, but you are completely ignoring the user's initial input.
Then, once you are inside the loop, you read in days
again before doing anything else. But you didn't prompt the user for another input yet. Eventually, hopefully they will figure out that your program is waiting for another input, and will type something in.
But if that input fails to read a number, or the number is out of range, then you are prompting the user and reading in days
yet again before jumping to the next loop iteration, which then starts the bad pattern all over again, waiting for an extra input without prompting the user to enter any input.
You should be reading in days
only 1 time per loop iteration.
Other people have suggested how to pigeon-hole the input validation into your existing loop structure. I would instead suggest a slightly different loop structure that should make the code a little easier to understand and follow:
#include <iostream>
#include <limits>
int main()
{
using namespace std;
int days;
cout << "How many days did you work this month? ";
do {
if (!(cin >> days)) {
cout << "Number of days should be... well, a number. Please re-enter: ";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
else if ((days < 1) || (days > 31)) {
cout << "Number of days should be between 1 and 31. Please re-enter:";
}
else {
break;
}
}
while (true);
cout << "Thank you for working " << days << "day(s)!";
return 0;
}