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.
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;
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.
Peter87 hasn't added usingnamespace 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.
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.
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:
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;
}
}
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;
}
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.
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
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().