简体   繁体   中英

Input Validation of int C++

I basically want to validate that I have an int and not a floating point number. What I currently have is:

int den1;
cout << "Enter denominator of first fraction" << endl;
cin >> den1;
while (den1 == 0){
   cout << "Enter a non-zero denominator" << endl;
   cin >> den1;
}

Is there a "test" to generate a boolean value for den1 == int? I'm trying to avoid using getline() because I don't want to use a string if it isn't necessary.

If you want to force your input to be of an integer type, then use an integer type for your input. If den1 is an int , it will not let you put a floating point value in it. That is, cin >> den1 will be an int value. If the user tries to input 3.14159 , only the 3 will be read (it will stop reading at the . . Note that the rest of the buffer will contain numbers as well, so if you don't clear it, the next attempt to read an integer will read 14159 .

EDIT

If you want to "force" the user to enter a valid integer, you can do something like this:

std::string line;

int value = 0;
bool valid = false;
do
{
    if (std::getline(std::cin, line))
    {
        if (std::string::npos == line.find('.'))
        {
            // no decimal point, so not floating point number
            value = std::stol(line);
            valid = true;
        }
        else
        {
            std::cin.clear();
        }
    }
} while (!valid);

Which is a lot of extra code compared to:

int value;
std::cin >> value;

You want to use something like

if (std::cin >> den) {
    // process den
}
else {
    // deal with invalid input
}

When an input operation fails, it sets std::ios_base::failbit on the stream and the stream converts to false instead of true . While the stream is in this failure mode, it won't read anything from the stream, ie, the failure mode as to be cleared, eg, using

std::cin.clear();

Once the failure mode is cleared, the offending character still sits in the stream. You can ignore the next character using, eg

std::cin.ignore();

or ignore all characters until the next newline:

std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

First of all, user input is always a string. Next, you need to define your goal more precisely. For example a reasonable thing to distinguish is whether the input can be parsed in its entirety as an integer, or as a floating point number, or neither. Here's one way to do this with iostreams, disregarding whitespace:

#include <iostream>
#include <sstream>
#include <string>

for (std::string line; std::getline(std::cin, line); )
{
    std::istringstream iss1(line), iss2(line);
    int n;
    double x;

    if (iss1 >> n >> std::ws && iss1.get() == EOF)
    {
        // have an int, use "n"
    }
    else if (iss2 >> d >> std::ws && iss2.get() == EOF)
    {
        // have a floating point number, use "d"
    }
    else
    {
        // failed to parse the input
        continue;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM