How do I disinfect qing?

Say I have a program that accepts integers. How to stop the program falling apart if the user enters a number out of range or a letter or something else?

+7
source share
6 answers

The base class is cin std::basic_istream . The input stream indicates the error to be recovered if it cannot retrieve the requested data from the stream. To check this error bit, you should use the std::basic_istream::fail() method - it returns true if a failure occurs, or false if everything is in order. It is important to remember that if there is an error, the data remains in the stream, and, of course, the bit (s) of the error must also be cleared using std::basic_istream::clear() . In addition, the programmer must ignore incorrect data, otherwise an attempt to read something else will not work again. For this purpose, you can use the std::basic_istream::ignore() method. As for the valid range of values, it must be checked manually. Ok, enough theory, here is a simple example:

 #include <limits> #include <iostream> int main() { int n = 0; for (;;) { std::cout << "Please enter a number from 1 to 10: " << std::flush; std::cin >> n; if (std::cin.fail()) { std::cerr << "Sorry, I cannot read that. Please try again." << std::endl; std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); continue; } if (n < 1 || n > 10) { std::cerr << "Sorry, the number is out of range." << std::endl; continue; } std::cout << "You have entered " << n << ". Thank you!" << std::endl; break; } } 

Hope this helps. Good luck

+2
source

I prefer to read input as strings and then sanitize them with boost::lexical_cast<> :

 #include <boost/lexical_cast.hpp> #include <iostream> #include <string> int main () { std::string s; while( std::cin >> s) { try { int i = boost::lexical_cast<int>(s); std::cout << "You entered: " << i << "\n"; } catch(const std::bad_cast&) { std::cout << "Ignoring non-number: " << s << "\n"; } } } 

Postscript: if you are allergic to Boost, you can use this lexical_cast implementation:

 template <class T, class U> T lexical_cast(const U& u) { T t; std::stringstream s; s << u; s >> t; if( !s ) throw std::bad_cast(); if( s.get() != std::stringstream::traits_type::eof() ) throw std::bad_cast(); return t; } 
+4
source

something like this should you need to clear the buffer after checking if i remember correctly

  if (cin.fail()) { cout<<"need to put a number"<<endl; cin.clear(); cin.ignore(); } 
+2
source

You can check if the reading was successful or not with cin.good() and cin.fail() .

See User Input for Integers - Error Handling

+1
source

If you do not want to add libraries to your code, you can also use do..while () operators. while you will be prompting for user input and then getting it into your variable, and then in the while part you can verify that this is the data that you expect if you do not continue to request data.

just another option ... although the answer already mentioned should work more than adequately

0
source

You can use the following code for the simplest and quickest verification of valid input in int:

 #include "stdafx.h" #include <iostream> using namespace std; int main() { int intb; while( !( cin>>intb ) ){ cin.clear (); cin.ignore (1000, '\n'); cout<<"Invalid input enter again: "<<endl; } cout<<"The value of integer entered is "<<b<<endl; return 0; } 

The while loop continues iterating until it receives the correct input. cin.clear () changes the state of error control. cin.ignore () removes the transparent input so that the new input can be accepted again. If this is not done, then the cycle will be in an infinite state.

0
source

All Articles