Как проверить пользовательский ввод как двойной в C ++? - PullRequest
18 голосов
/ 18 июля 2010

Как я могу проверить, является ли вход действительно двойным?

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...

Приведенный выше код бесконечно выводит оператор Invalid Input!, поэтому он не запрашивает другой ввод. Я хочу запросить ввод, проверить, является ли он законным ... если это двойное число, продолжай ... если оно НЕ двойное, повторить запрос.

Есть идеи?

Ответы [ 7 ]

14 голосов
/ 18 июля 2010

Попробуйте:

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
  }
}

Это в основном очищает состояние ошибки, затем считывает и удаляет все, что было введено в предыдущей строке.

1 голос
/ 18 июля 2010

failbit будет установлено после использования оператора извлечения, если произошла ошибка разбора, есть пара простых тестовых функций good и fail, которые вы можете проверить.Они в точности противоположны друг другу, потому что они обрабатывают eofbit по-разному, но в этом примере это не проблема.

Затем вы должны очистить failbit перед повторной попыткой.

Как говорит Касабланка, вы также должны отбросить нечисловые данные, оставшиеся во входном буфере.

Итак:

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...
0 голосов
/ 30 ноября 2018

Я бы использовал:

double x;

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

или

double x;

while ((std::cout << "> ") && !(std::cin >> x)) {
  std::cin.clear();
  std::cin.ignore(2147483647, '\n');
  std::cout << "Error.\n";
}
0 голосов
/ 05 июля 2016
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;
}
}
0 голосов
/ 05 мая 2012
#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;
}
0 голосов
/ 18 июля 2010

Одним из способов является проверка на равенство с плавающей точкой.

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;
    }
}
0 голосов
/ 18 июля 2010

Я бы использовал scanf вместо cin.

Функция scanf возвращает количество совпадений из целевой строки. Чтобы убедиться, что был проанализирован правильный double, убедитесь, что возвращаемое значение scanf равно 1.

Edit:
Изменено fscanf на scanf.

...