Checking input is numeric

Apr 16, 2015 at 10:47am
I am trying to create a basic calculator program, and I want to make sure that the user input is numeric, and if it is not, give an option to return to the main menu.

The problem I am having is that when the program gets to the point where it recognises non-numeric user input, it displays the cout statements, but not the cin option.

I'm not really sure if the switch statement is the best way to accomplish the loop I want, but I am very confused as to why the cin option will not work. I feel I am missing something obvious here, but I have tried changing most aspects of this section of code, and the problem remains.

Any ideas?

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
void data_input();

void operation_menu();

double x, y;

int main() {

	data_input();
	
	return 0;
}

void data_input() {
	
	char loop;

	std::cout << "Enter two numbers\n";
	std::cin >> x >> y;

	if ((x == false) || (y == false)) {		
		
		std::cout << "Input not recognised. Would you like to try again?\n";
		std::cout << "(Y)es\n";
		std::cout << "(N)o\n";
		
		std::cin >> loop;
		
		switch (loop) {
				
				case 'y':
				operation_menu();
                                break;
				
				case 'n':
				std::cout << "Exiting program\n";
				break;
				
			deafult:
			std::cout << "Error.\n";			
			std::cout << "Please try again\n";
				break;
		}	
	}

	else {
		operation_menu();
	}
}

void operation_menu() {
	
	std::cout << "operation_menu()";	
}
Last edited on Apr 16, 2015 at 10:50am
Apr 16, 2015 at 11:38am
As a general rule you can't write text into a double/float/int. You can however write a number to a string
Check out stod
cplusplus.com/reference/string/stod/
Apr 16, 2015 at 12:59pm
cin goes into error state if the input is not valid. You can check that like so:
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
void data_input() {
	
	char loop;

	std::cout << "Enter two numbers\n";

	if (std::cin >> x >> y) {		
		operation_menu();
	}
	else {

		std::cin.clear(); // Note: Required to clear the error state
		std::cin.ignore (numeric_limits<streamsize>::max()); // Note: remove all remaining characters in the stream. #include <limits>
		
		std::cout << "Input not recognised. Would you like to try again?\n";
		std::cout << "(Y)es\n";
		std::cout << "(N)o\n";
		
		std::cin >> loop;
		
		switch (loop) {
				
				case 'y':
				operation_menu();
                                break;
				
				case 'n':
				std::cout << "Exiting program\n";
				break;
				
			deafult:
			std::cout << "Error.\n";			
			std::cout << "Please try again\n";
				break;
		}	
	}
}
Apr 16, 2015 at 1:00pm
When you encounter illegal input (e.g. trying to put a string into a double) the state of your input stream (cin) will be in error. Until you clear the error and flush the istream buffer you'll be stuck, because the illegal input will still be in the buffer, and each time you read from cin, it'll happen all over again.
Also, x and y are double, don't try and treat them like booleans. The state of the stream tells you if you're successful or not. You should be checking the state of the stream not the value in x and y.
Try replacing line 21 with:

1
2
3
if (!std::cin) {
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n' );


Also, consider not doing std::cin >> x >> y; Instead doing x and y individually, so you can handle each case independently.
Also remember to #include <limits> if you use the fragment above, and you spelt "default" wrong in line 39.
Apr 20, 2015 at 2:17pm
Thanks very much guys, all sorted now!
Topic archived. No new replies allowed.