cin for an int inputing a char causes Loop that is supposed to check input to go wild
When an error occurs when reading from a stream, an error flag gets set and no more reading is possible until you clear the error flags. That's why you get an infinite loop.
cin.clear(); // clears the error flags
// this line discards all the input waiting in the stream
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Also, it's wrong to use the results of input operation if you don't know whether the read succeeded in the first place. You can't make assumptions about the value of iAuswahl
. That's one of most often made errors by newbies using streams. Always check if the input operation was ok. This is most easily done by using operator>>
in boolean context:
if (cin >> some_obj) {
// evaluates to true if it succeeded
} else {
// something went wrong
}
And, my oh my, this line
while (iAuswahl != 1 && iAuswahl != 2 && iAuswahl != 3 && iAuswahl != 4 && iAuswahl != 5 && iAuswahl != 6 && iAuswahl != 7 && iAuswahl != 8 && iAuswahl != 9)
can be just this:
while (iAuswahl < 1 || iAuswahl > 9)
A correct loop could look something like this:
while (true)
{
if ((cin >> iAuswahl) && (iAuswahl >= 1) && (iAuswahl <= 9)) break;
std::cout << "error, try again\n";
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
C++ Putting a character into a cin for a while loop causes the loop to execute outside of it
From another Stack Overflow question...
When an error occurs when reading from a stream, an error flag gets
set and no more reading is possible until you clear the error flags.
That's why you get an infinite loop.cin.clear(); // clears the error flags
// this line discards all the input waiting in the stream
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Infinite loop created when inputting yy into a char variable that should only take a single character such as 'y' or 'n', nn does not break code
Does it only take the first value?
Yes, the >>
formatted extraction operator, when called for a single char
value, will read the first non-whitespace character, and stop. Everything after it remains unread.
why does 'yy' cause a loop
Because the first "y" gets read, for the reasons explained above. The second "y" remains unread.
This is a very common mistake and a misconception about what >>
does. It does not read an entire line of typed input. It only reads a single value after skipping any whitespace that precedes it.
Your program stops until an entire line of input gets typed, followed by Enter
, but that's not what >>
reads. It only reads what it's asked to read, and everything else that gets typed in remains unread.
So the program continues to execute, until it reaches this part:
cin >> bettingAmount;
At this point the next unread character in the input is y
. The >>
formatted extraction operator, for an int
value like this bettingAmount
, requires numerical input (following optional whitespace). But the next character is not numerical. It's the character y
.
This results in the formatted >>
extraction operator failing. Nothing gets read into bettingAmount
. It remains completely unaltered by the >>
operator. Because it is declared in global scope it was zero-initialized. So it remains 0.
In addition to the >>
extraction operator failing, as part of it failing it sets the input stream to a failed state. When an input stream is in a failed state all subsequent input operation automatically fail without doing anything. And that's why your program ends up in an infinite loop.
Although there is a way to clear the input stream from its failed state this is a clumsy approach. The clean solution is to fix the code that reads input.
If your intent is to stop the program and enter something followed by Enter
then that's what std::getline
is for. The shown program uses it to read some of its initial input.
The path of least resistance is to simply use std::getline
to read all input. Instead of using >>
to read a single character use std::getline
to read the next line of typed in input, into a std::string
, then check the the string's first character and see what it is. Problem solved.
cin >> bettingAmount;
And you want to do the same thing here. Otherwise you'll just run into the same problem: mistyped input will result in a failed input operation, and a major headache.
Why do you need this headache? Just use std::getline
to read text into a std::string
, construct a std::istringstream
from it, then use >>
on the std::istringstream
, and check its return value to determine whether it failed, or not. That's a simple way to check for invalid input, and if something other than numeric input was typed in here, you have complete freedom on how to handle bad typed in input.
C++ Input a char instead of int lead to endless loop. How to check the wrong input?
Simply check if the input is a number first and then append it to the array
int x;
std::cin >> x;
while(std::cin.fail())
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
std::cout << "Bad entry. Enter a NUMBER: ";
std::cin >> x;
}
a[i] = x;
C++ Checking if input is a int and redo the input until it is a int
Reference: cin for an int inputing a char causes Loop that is supposed to check input to go wild
This is a duplicate but the canonical answer is to do:
std::cin.clear(); // clears the error flags
// this line discards all the input waiting in the stream
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Then do something like:
int year;
while (!(std::cin >> year)) {
std::cin.clear(); // clears the error flags
// this line discards all the input waiting in the stream
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "error" << std::endl;
}
// do something with year
So if your input looked like:
a
b
c
42
It will print error three times.
C++: Why does inputting a char for an int variable cause recursion to go crazy?
The fact that you're calling main
aside (you could just extract everything to a separate function), the problem is that when you enter something that a stream can't parse, it enters an error state where it returns from every operation immediately without doing anything. You need to check for the error state and reset the stream to get out of this.
Infinite loop after receiving input and testing to see if it's an int in C++
If the input stream doesn't contain an integer when you do cin >>
, the stream enters an error state, which must be explicitly
steps
cleared (cin.clear()
). Until then, the error state remains, and all
further attempts to input will be treated as no-ops.
Related Topics
How to Avoid Precompiled Headers
Ctrl + C Interrupt Event Handling in Linux
Convert Wstring to String Encoded in Utf-8
Prevent User Process from Being Killed with "End Process" from Process Explorer
Connected Components in Opencv
Tackling Class Imbalance: Scaling Contribution to Loss and Sgd
Is Left and Right Shifting Negative Integers Defined Behavior
Copy Constructor of Template Class
What Happens If You Increment an Iterator That Is Equal to the End Iterator of an Stl Container
How Can an Incomplete Type Be Used as a Template Parameter to Vector Here
What Is Forward Declaration in C++
Cout or Printf Which of the Two Has a Faster Execution Speed C++
Range-Based for Loop on a Dynamic Array
Pointer to Array with Const Qualifier in C & C++
Undefined Reference to '_Gxx_Personality_Sj0'
More Elegant Way to Check for Duplicates in C++ Array
Workaround for Template Argument Deduction in Non-Deduced Context