Как я могу проверить ввод пользователя как двойной в С++?

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

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!, поэтому его не запрашивает другой ввод. Я хочу запросить ввод, проверьте, является ли это законным... если его двойник, продолжайте... если он НЕ двойной, подскажите еще раз.

Любые идеи?

Ответы

Ответ 1

Попробуйте следующее:

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

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

Ответ 2

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

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

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

Итак:

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

Один из способов - проверить равенство плавающего числа.

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

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

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

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