Public Group

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

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

## 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 on other sites
cin >> menu_choice;// If menu_choice couldn't be readif(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 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 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 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 on other sites
Alternatively you can use
cin.sync()
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.

• 10
• 17
• 9
• 13
• 41