Program exits if non-integer is entered

Aug 1, 2014 at 10:17pm
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 Aug 1, 2014 at 10:38pm
Aug 1, 2014 at 10:58pm
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/
Aug 2, 2014 at 12:09am
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.
Aug 2, 2014 at 6:21am
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');
Aug 3, 2014 at 1:28am

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 Aug 3, 2014 at 1:31am
Aug 3, 2014 at 7:51am
When you type '123+', the xInput will become '123' and therefore the next input operation attempts to read the non-numeric '+'.
Aug 3, 2014 at 10:38pm
hello keskiverto,

Yes, I guess thats the issue here. Anyways, is there a way to fix it?
Aug 4, 2014 at 9:19am
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.