Reputation:
So I'm curious as to why this happens.
int main()
{
bool answer = true;
while(answer)
{
cout << "\nInput?\n";
cin >> answer;
}
return 0;
}
Expected behavior: 0 - Exits program, 1 - Prompts again, Any non-zero integer other than 1 - Prompts again
Actual behavior: 0 - As expected, 1 - As expected, Any non-zero integer other than 1 - Infinite loop
From http://www.learncpp.com/cpp-tutorial/26-boolean-values/
One additional note: when converting integers to booleans,
the integer zero resolves to boolean false,
whereas non-zero integers all resolve to true.
Why does the program go into an infinite loop?
Upvotes: 23
Views: 4049
Reputation: 355187
In effect, the operator>>
overload used for reading a bool
only allows a value of 0
or 1
as valid input. The operator overload defers to the num_get
class template, which reads the next number from the input stream and then behaves as follows (C++11 §22.4.2.1/6):
If the value to be stored is
0
thenfalse
is stored.If the value is
1
thentrue
is stored.Otherwise
true
is stored andios_base::failbit
is assigned toerr
.
(err
here is the error state of the stream from which you are reading; cin
in this case. Note that there is additional language specifying the behavior when the boolalpha
manipulator is used, which allows booleans to be inserted and extracted using their names, true
and false
; I have omitted these other details for brevity.)
When you input a value other than zero or one, the fail state gets set on the stream, which causes further extractions to fail. answer
is set to true
and remains true
forever, causing the infinite loop.
You must test the state of the stream after every extraction, to see whether the extraction succeeded and whether the stream is still in a good state. For example, you might rewrite your loop as:
bool answer = true;
while (std::cin && answer)
{
std::cout << "\nInput?\n";
std::cin >> answer;
}
Upvotes: 24
Reputation: 3733
Because operator>>
fails if the input is not 0 or 1, and when it fails, it does not consume input. So the loop consists of reading the digit and then un-reading it, repeatedly.
Try changing the code like this to see it:
if (cin >> answer) {
cout << answer << endl;
} else {
cerr << "oops" << endl;
break;
}
Upvotes: 15