How to catch invalid input in c++?

27,487

Solution 1

You will need to #include <limits>

int x;
std::cout << "Enter a number: ";
std::cin >> x;
while(std::cin.fail()) {
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
    std::cout << "Bad entry.  Enter a NUMBER: ";
    std::cin >> x;
}
std::cout << "x = " << x << std::endl;

There's a template for you.

Solution 2

By default, C++ streams don't throw upon ill-formed input: it isn't exceptional that input is wrong. It is normal. The C++ approach to indicate input failure is to put the stream into failure state, i.e., to set the state flag std::ios_base::failbit. The easiest way to test for wrong input is to use something like

if (in >> value) {
    process(value);
}
else {
    deal_with_input_error(in);
}

Dealing with the input error typically amounts to clearing the stream's state (as long as it is failure mode it won't deal with the actual stream at all) and then to ignore() one or more of the offending characters.

If you really want to get an exception you can set an exception mask:

in.exceptions(std::ios_base::failbit);
try {
    in >> value;
}
catch (std::ios_base::failure const& ex) {
    // deal with the error
}

Whenever in.exceptions() & in.rdstate() is non-zero at the end of any of the members dealing with the state bits or the exception mask is called an exception thrown (i.e. calling in.exception(std::ios_base::failbit) may itself throw an exception). The exception thrown is of type std::ios_base::failure.

I recommend not to use the exception facilities in IOStreams! Input errors are normal and exceptions are for, well, exceptional errors. Using the conversion to bool after having read a value works rather well.

Solution 3

Streams don't throw exceptions by default (they can be configured to do so).

The usual code to read an int is:

int a;
if (std::cin >> a) {
    # OK
} else {
    # error
}

But do be sure that you know what >> actually does here. Specifically, newcomers to C++ are sometimes surprised that it doesn't necessarily read a whole line. So, if you want to validate a whole line of input, or for that matter if you want to retry on failure then you need more code.

Share:
27,487
JohnBobSmith
Author by

JohnBobSmith

Updated on August 19, 2020

Comments

  • JohnBobSmith
    JohnBobSmith over 3 years

    I am a (somewhat) experienced python programmer trying to migrate to C++. I want to be able to catch invalid user input. For instance, if a variable requires an integer, and the user types a string, I want to catch that error. In python 3, the syntax is:

    try:
        #block of code you want to run
    except ValueError:
        #Block of code to be run if the user inputs an invalid input
    

    In c++ I read that the syntax is Try, catch. I am trying to do that, but its not working. here is my code in c++:

    #include "Calculator.h"
    #include <iostream>
    #include <exception>
    
    using namespace std;
    
    Calculator::Calculator()
    {
    }
    
    int Calculator::Calc()
    {
        cout << "Enter a number " << endl;
    try
    {
        cin >> a;
    }
    catch (logic_error)
    {
        cout << "An error has ocurred! You have entered an invalid input!"
    }
    

    How can I catch invalid input in c++? Yes, I am using a header file for this class. If you need those contents, let me know. I will continue to search the web and post if I have found an answer!