Program exits if non-integer is entered

How to make this program prevent from terminating after entering non-integer such as "letters",?

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
#include <iostream>
#include <stdlib.h>
#include <time.h>


using namespace std;

int main()
{	
	srand(static_cast<unsigned int>(time(0)));

	int xRandom = rand() % 1000;
	int xInput;
	
	cout << xRandom << endl;

	while (cin >> xInput)
	{	

		if (xInput != xRandom)
		{
			cout << "error\n";
		}

		xRandom = rand() % 1000;
		cout << xRandom << endl;

	}

}
Last edited on
The stream's (cin) failbit is set. It must be cleared and then the offending characters must bve discarded from the stream before trying to read an integer again.

Note that the stream might be in error state not only due to the user writing a word instead of number, but also when EOF has been reached.

See http://www.cplusplus.com/reference/istream/istream/
Hi, yes I think I had read a tutorial that is quite similar than your thought

they added something like

cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

I tried to add this but nothing really works, I #include <limits>
also.
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
#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main()
{    
    srand(static_cast<unsigned int>(time(0)));

    int xRandom = rand() % 1000;
    int xInput;
    
    cout << xRandom << endl;

    while (true)                    // loop forever
    {
        while (!(cin >> xInput))    // loop until a valid integer
        {
            cout << "not numeric, try again: ";
            cin.clear();            // reset error flags
            cin.ignore(1000, '\n'); // discard characters from input buffer    
        }

        if (xInput != xRandom)
        {
            cout << "error\n";
        }

        xRandom = rand() % 1000;
        cout << xRandom << endl;
    }

}

You could replace line 22 with cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

Hi chervil,

thanks I had follow your tips and it does work so far.

I had remodeled the code in a way that it does not give a random number again until the previous random number is entered correctly.

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

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main()
{
	srand(static_cast<unsigned int>(time(0)));

	int xRandom = rand() % 1000;
	int xInput;

	cout << "\t" << xRandom << endl;

	while (true)                    // loop forever
	{
		while (!(cin >> xInput))    // loop until a valid integer
		{
			cout << "not numeric, try again: ";
			cin.clear();            // reset error flags
			cin.ignore(1000, '\n'); // discard characters from input buffer    
		}

		do         // loop until previous random number is  entered correctly
		{
			if (xInput != xRandom)
			{
				cout << "error\n";

				while (!(cin >> xInput))    
				{
					cout << "not numeric, try again:\n ";
					cin.clear();            
					cin.ignore(1000, '\n'); 
				}
			}
		} while (xInput != xRandom);

		xRandom = rand() % 1000;
		cout << "\t" << xRandom << endl;
	}

}


However, there is one thing I wanted to change, if I enter a number followed by a non-numeric character (ex. "123+" or "432sd") it outputs

" 908
123+
error
not numeric, try again: "

it think it bypasses "while (!(cin >> xInput))" Im thinking I should re-input the "908" first after "error".
Last edited on
When you type '123+', the xInput will become '123' and therefore the next input operation attempts to read the non-numeric '+'.
hello keskiverto,

Yes, I guess thats the issue here. Anyways, is there a way to fix it?
Yes, by program logic.
"123" is one input. "+" is the next input. Writing "123+" is the same as writing
123
+

Also, writing "123 205 42" is same as typing each number separately; the program can do three cin>>

Therefore, your program has to cope with the fact that each read from the stream can be good or bad. Your current code is too complex and has unnecessary repeats.

You need only one loop. Ask for number only once per iteration. Skip rest of loop, if you had to clear.
Generate random number only after success. Provide a means to quit the loop (EOF is one).
Topic archived. No new replies allowed.