Jump to content
  • Advertisement
Sign in to follow this  
Liam78

noob needs help with input validation in c/c++

This topic is 4733 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

The following piece of code works if the user enters an interger, but... How can i make it so the program will not crash when a user enters a char? for example the user enters "g" and instead of crashing it displays "invalid choice pick again" int validation(void) { int menu_choice; while(1) { cin >> menu_choice; if(menu_choice == 1 || menu_choice == 2 || menu_choice == 3) { return(menu_choice); } else { cout<<"invalid choice pick again "; } } }

Share this post


Link to post
Share on other sites
Advertisement
cin >> menu_choice;

// If menu_choice couldn't be read
if(cin.fail())
{
// Discard the remainder of the line
// numeric_limits is in <limits>
cin.ignore(numeric_limits<int>::max, '\n');

// Clear the flags
cin.clear()

// Print an error message
cout<<"invalid choice pick again ";

// Loop
continue;
}

Share this post


Link to post
Share on other sites
There also exists an idiom where you do the reading as part of the loop condition; the stream, after trying to read a value and failing to do so, is in a "failed state", and such a stream is considered "false" in a boolean context. The net result is that you can write, for example, "while (stream >> foo)", which reads as "while stream can be read into foo". This lets you do something like:


int getNumber() {
int result;
// For as long as we either can't read, or we could but the value is bad
while (!(cin >> result) || result < 1 || result > 3) {
// then we have some junk and must clean up.
cout << "invalid choice pick again" << endl;
cin.ignore(numeric_limits<int>::max, '\n');
cin.clear();
}
// Otherwise, we read in a valid value and can return it.
return result;
}


This is useful enough that you'll want to make this function a bit more general in the future :)

Another approach is to read the data a full line at a time, and then re-parse the read lines. We do the parsing with a std::stringstream, and if it fails, no reset is required - we just try again by making a new stringstream with the next line of input.


int getNumber() {
string line;
// For as long as we can grab lines of input,
while (getline(cin, line)) {
// try to interpret the line beginning as an integer.
stringstream ss(line);
int result;
// and if we can do so, return the value.
if (ss >> result) return result;
// Otherwise, just let ss be destructed, and reconstructed for the next line.
// This approach also lets us easily check for garbage input after the
// number, if desired.
}
// Somehow we reached the end of input.
throw std::exception(); // TODO: make this more informative
}

Share this post


Link to post
Share on other sites
thx for the helps guys, one last thing how do i insert code blocks in the forums,,,
is it something like


<code>
example code here
</code>

Share this post


Link to post
Share on other sites
You can use the [code] and [source][/source] tags. [source][/source] gives you the white box and [code] gives you tt formated text.

Share this post


Link to post
Share on other sites
Alternatively you can use
cin.sync()
instead of
cin.ignore(numeric_limits<int>::max, '\n');


Besides being more concise to use (and not depending on the numeric limits header), I can't give you any advantages or drawbacks to this method as I haven't observed any thus far.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!