Validating Data to prevent characters from being entered

Hi, I'm working on validation of integer data, I've made a gas mileage calculator which allows the input of current mileage, previous mileage and amount of gallon put in a and object car but I'm having trouble figuring out how to prevent the user from entering in a character. Can some explain the concept of preventing users from inputing characters to me? I'm good with integers but when I get to characters it always throws me.

Thanks in advance.
Last edited on
I assume you get your input from std::cin.

Reading an integer you just do
1
2
int n;
std::cin >> n;


This might fail if the user enters something else than an integer. To check if the read was successful you can put the std::cin >> n; inside an if or while statement.

Example:
1
2
3
4
5
6
7
8
9
std::cout << "Enter an integer: ";
int n;
while (!(std::cin >> n))
{
    std::cin.clear(); // clear the error flags
    std::cin.ignore(INT_MAX, '\n'); // discard the row
    std::cout << "Invalid input! Try again: ";
}
std::cout << "Well done! You have entered the integer " << n << std::endl;

Last edited on
Thanks I'll give that a try. I can kind of see what it's doing, could you explain it to me a little more so I can grasp the code? I'm not familiar with std::cin. The :: makes it look to me like there's an object involved.

Thanks again!
Last edited on
Peter87 hasn't added using namespace std; within his code.

Quote from a google search:
Explained as simply as possible, namespaces allows us to group a set of global classes, objects and/or functions under a name. If you specify using namespace std then you don't have to put std:: throughout your code. The program will know to look in the std library to find the object. Namespace std contains all the classes, objects and functions of the standard C++ library.
Ah! ok, thank you, I always put using namespace std at the top so I can get away with not putting ing the code.

Thanks Lynx!

I'm damn proud today, I made my first object.. today and object... tomorrow the world!
To be fair, that's probably what you what (what Peter87 said,) but it will not stop the user from entering something like:
"10.8x" or "20 30 40"

See, the input (for int) stops reading at the first non-number character (like the '.') or the first whitespace (unless the first character is a '+' or '-'). If you really want to make sure they enter an int and nothing else you want to make sure that the only thing left in the input stream (cin) is the newline character (or possibly extra whitespace.) Something like:
1
2
3
4
5
6
7
8
9
10
if( !(cin >> x) )
    ... //error
else { //so far we're good
    istringstream sin = cin;
    sin >> string();
    if( sin.eof() )
        ... //good
    else
        ... //there was extra stuff in the stream
}

Also, you can read the characters in one at a time to validate the input that way, but that's a bit over kill.
I prefer Mathead's way!

Here's a function I made for taking menu choices a while back. I return 999 if the range is not correct, as I used this within a switch statement.

If there is more than one menu, then you can output different error messages within the menus switch statement differently. Which is why I return a value, rather then outputting a message:

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
int streamInt( int low, int high )
{
	//include int's passed to function
	++high;
	--low;

	std::string input;
	int choice = 0;

	while( true )
	{
		//get the line from the console up until
		//the '\n' NEWLINE character
		std::getline( std::cin, input, '\n' );

		std::stringstream ss( input );

		//if the stringstream goes in to the int choice
		//and the number entered was in range, raturn the int
		if( ( ss >> choice ) && ( choice > low ) && ( choice < high ) )
			return choice;

		//output an error message or return something
		return 999;
	}
}


You could then call this in the following way:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int choice = streamInt( 1, 3 ); //3 menu options

switch( choice )
{
    case 1:
        //code
        break;

    case 2:
        //code
        break;

    case 3:
        //code
        break;

    case 999:
        std::cout << "Error from input...";
        break;
}
Last edited on
Why while(true)? The loop runs once no mater the control path (as far as I can see.)
Also you could use ( choice >= low ) && (choice <= high ) to avoid the increment and deincrement at the top of the function.
Last edited on
you guys are good. I good things to study now, thank you both!
Why while(true)? The loop runs once no mater the control path (as far as I can see.)
I used to have an error message( cout ) there, but I changed it to a return, never bothered to change the while loop, because there was no need too! lol

Also you could use ( choice >= low ) && (choice <= high ) to avoid the increment and deincrement at the top of the function.
I made this a while back, no idea why I did that, and haven't changed it... ahaha. I guess "If it's not borke, don't fix it!" :D
@Lynx876: Fair enough... Just though I'd mention it.
@Scottm4321: No problem.
Last edited on
One way that I was taught on validating data was to read the data into a char array using a cin.getline(). Then you loop using a for(int i=0;i<strlen(array);i++) to check each character individually, while allowing for while spaces, decimal points, etc if need be. You would check each digit with isdigit().
Topic archived. No new replies allowed.