Stuck in infinite loop when executing else statement



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>

using namespace std;

int input;
bool quit = false;
char another;

int main() {

	while(!quit) {

		cout << "Check whether a number is positive, negative, or zero:" << endl;
		cout << "------------------------------------------------------" << endl;
		cout << "Input a number: " << endl;
		cin >> input;

		if (input == 0) {
			cout << "The entered number is zero." << endl;

		}
		else if (input > 0) {
			cout << "The entered number is positive." << endl;
		}
		else if (input < 0) {
			cout << "The entered number is negative." << endl;
		}
		else {
			cout << "Please enter a number!" << endl;
			cin >> input;
		}

		cout << "Check another number? ";
		cin >> another;
		cout << " " << endl;

		if (another == 'y' || another == 'Y') {
			quit = false;
		}
		else if (another == 'n' || another == 'N') {
			quit = true;
		}
		else {
			cout << "Please enter only (Y/N): " << endl;
			cout << "Check another number? ";
			cin >> another;
		} 
	}
}




If I type ANY character other than a number, it will loop forever.
How do I prevent that? Changing int input; to char input; creates different problems, such as not being able to tell when a number is negative.

Thanks
Last edited on
When you have:
1
2
3
int input;
...
cin >> input;

and you enter something other than a number, the cin stream goes into an error state. It will stay there until you explicitly clear the error state. The idea is that you need to skip past the bad characters, but the compiler doesn't know exactly how far ahead it should skip - that's application dependent.

For a case like this you probably want to ignore everything through the next end-of-line character:
1
2
3
4
5
6
#include <limits>
...
// Clear the error state.
cin.clear();
// ignore to the next newline character, even if that's a bajillion characters ahead.
cin.ignore(numeric_limits<streamsize>::max(), '\n');


Put this in a loop that reads the number. Notice that the loop exits from the middle with a break statement, not the beginning or the end.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <iostream>
#include <limits>

using namespace std;

int input;
bool quit = false;
char another;

int main() {

	while(!quit) {

		cout << "Check whether a number is positive, negative, or zero:" << endl;
		cout << "------------------------------------------------------" << endl;

		while (true) {
		    cout << "Input a number: " << endl;
		    cin >> input;
		    if (cin) break;

		    // If you get here then they entered something
		    // other than a number
		    cin.clear();
		    cin.ignore(numeric_limits<streamsize>::max(), '\n');
		    cout << "Please enter a number\n";
		}

		if (input == 0) {
			cout << "The entered number is zero." << endl;

		}
		else if (input > 0) {
			cout << "The entered number is positive." << endl;
		}
		else if (input < 0) {
			cout << "The entered number is negative." << endl;
		}


		cout << "Check another number? ";
		cin >> another;
		cout << " " << endl;

		if (another == 'y' || another == 'Y') {
			quit = false;
		}
		else if (another == 'n' || another == 'N') {
			quit = true;
		}
		else {
			cout << "Please enter only (Y/N): " << endl;
			cout << "Check another number? ";
			cin >> another;
		} 
	}
}


If I type ANY character other than a number, it will loop forever.

Assuming that you're talking about the entry for "input" you need to realize that an int can only accept numerical input. If you try to enter something else the stream will fail, which is probably the reason for your infinite loop, and the affected variable is default initialized (in this case to zero). To avoid this issue you need to validate the entry more thoroughly. The first thing you probably should test is the status of the stream, if it is in a fail state you need to clear the stream state and remove all the "bad" characters from the stream.

Something like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...

int main() {
    // avoid global variables whenever possible.
    int input;
    bool quit = false;
   char another;

	while(!quit) {

		cout << "Check whether a number is positive, negative, or zero:" << endl;
		cout << "------------------------------------------------------" << endl;
		cout << "Input a number: " << endl;
		cin >> input;

             if(!cin) // If cin is in a fail state, fix it.
             {
                 cin.clear(); // First clear the error flags.
                 cin.ignore(1000, '\n');  // Now clear the input buffer.
                 continue;  // Now go back to the beginning of the loop.
             }
...


Thank you dhayden and jlb!

I did the following fixes to my code and now it seems to work without fail.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <iostream>
#include <limits>

using namespace std;

int input;
bool quit = false;
char another;
bool quit2 = false;

int main() {

	while(!quit) {

		cout << "Check whether a number is positive, negative, or zero:" << endl;
		cout << "------------------------------------------------------" << endl;
		cout << "Input a number: " << endl;

		while (true) {
		cin >> input;
		if (cin) break;
		    cin.clear();
		    cin.ignore(numeric_limits<streamsize>::max(), '\n');
		    cout << "Please enter a number\n";
		}

		if (input == 0) {
			cout << "The entered number is zero." << endl;

		}
		else if (input > 0) {
			cout << "The entered number is positive." << endl;
		}
		else if (input < 0) {
			cout << "The entered number is negative." << endl;
		}

		quit2 = false;

		while (!quit2){
		cout << "Check another number? ";
		cin >> another;
		cout << " " << endl;

		if (another == 'y' || another == 'Y') {
			quit = false;
			quit2 = true;
		}
		else if (another == 'n' || another == 'N') {
			quit = true;
			quit2 = true;
		}
		else {
			cout << "Please enter only (Y/N): " << endl;
			quit = false;
		}
		}
	}
}




I googled around before posting here and say the cin.clear() suggestions on other forums, but didn't realize I needed to use #include <limits> for it to work.
<limits> is needed for getting the maximum size of the stream. Line 23 could have been std::cin.ignore(32767, '\n');, or any largish number, and still worked.
Topic archived. No new replies allowed.