Cin for an Int Inputing a Char Causes Loop That Is Supposed to Check Input to Go Wild

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 >>
steps
, the stream enters an error state, which must be explicitly
cleared (cin.clear()). Until then, the error state remains, and all
further attempts to input will be treated as no-ops.



Related Topics



Leave a reply



Submit