how do I validate user input as a double in C++?

2019-01-01 14:16发布

问题:

How would I check if the input is really a double?

double x;

while (1) {
    cout << \'>\';
    if (cin >> x) {
        // valid number
        break;
    } else {
        // not a valid number
        cout << \"Invalid Input! Please input a numerical value.\" << endl;
    }
}
//do other stuff...

The above code infinitely outputs the Invalid Input! statement, so its not prompting for another input. I want to prompt for the input, check if it is legitimate... if its a double, go on... if it is NOT a double, prompt again.

Any ideas?

回答1:

Try this:

while (1) {
  if (cin >> x) {
      // valid number
      break;
  } else {
      // not a valid number
      cout << \"Invalid Input! Please input a numerical value.\" << endl;
      cin.clear();
      while (cin.get() != \'\\n\') ; // empty loop
  }
}

This basically clears the error state, then reads and discards everything that was entered on the previous line.



回答2:

failbit will be set after using an extraction operator if there was a parse error, there are a couple simple test functions good and fail you can check. They are exactly the opposite of each other because they handle eofbit differently, but that\'s not an issue in this example.

Then, you have to clear failbit before trying again.

As casablanca says, you also have to discard the non-numeric data still left in the input buffer.

So:

double x;

while (1) {
    cout << \'>\';
    cin >> x;
    if (cin.good())
        // valid number
        break;
    } else {
        // not a valid number
        cout << \"Invalid Input! Please input a numerical value.\" << endl;
        cin.clear();
        cin.ignore(100000, \'\\n\');
    }
}
//do other stuff...


回答3:

One way is to check for floating number equality.

double x;

while (1) {
    cout << \'>\';
    cin >> x;
    if (x != int(x)) {
        // valid number
        break;
    } else {
        // not a valid number
        cout << \"Invalid Input! Please input a numerical value.\" << endl;
    }
}


回答4:

#include <iostream>
#include <string>

bool askForDouble(char const *question, double &ret)
{
        using namespace std;
        while(true)
        {
                cout << question << flush;
                cin >> ret;
                if(cin.good())
                {
                        return true;
                }
                if(cin.eof())
                {
                        return false;
                }
                // (cin.fail() || cin.bad()) is true here
                cin.clear();  // clear state flags
                string dummy;
                cin >> dummy; // discard a word
        }
}

int main()
{
        double x;
        if(askForDouble(\"Give me a floating point number! \",x))
        {
                std::cout << \"The double of it is: \" << (x*2) << std::endl;
        } else
        {
                std::cerr << \"END OF INPUT\" << std::endl;
        }
        return 0;
}


回答5:

bool is_double(double val)
{
bool answer;
double chk;
int double_equl = 0;     
double strdouble = 0.0;
strdouble = val;           
double_equl = (int)val;
chk = double_equl / strdouble;
if (chk == 1.00)
{
 answer = false; // val is integer
 return answer;
} else {
answer = true;  // val is double
return answer;
}
}


回答6:

I would use:

double x;

while (!(std::cin >> x)) {
  std::cin.clear();
  std::cin.ignore(2147483647, \'\\n\');
  std::cout << \"Error.\\n\";
}

or

double x;

while ((std::cout << \"> \") && !(std::cin >> x)) {
  std::cin.clear();
  std::cin.ignore(2147483647, \'\\n\');
  std::cout << \"Error.\\n\";
}


回答7:

I would use scanf instead of cin.

The scanf function will return the number of matches from the target string. To make sure a valid double was parsed, make sure the return value of scanf is 1.

Edit:
Changed fscanf to scanf.