C ++ Как проверить входную переменную с плавающей точкой для правильного ввода - PullRequest
0 голосов
/ 24 ноября 2010

Я пишу программу, которая действует как калькулятор; на основе введенного пользователем символа он выполняет определенную операцию. Структура программы, кажется, работает нормально, но я хотел бы иметь возможность проверить ошибочный ввод. После получения переменной с плавающей точкой, есть ли способ проверить, не содержит ли она никаких символов, кроме цифр и десятичных знаков? Я пробовал isdigit, и это:

if (!(cin >> x)) {
    cout << "You did not enter a correct number!" << endl; 
    return;
}

Но, похоже, ничего не работает.

Вот пример одной из простых функций управления, которые я использую:

void Add(){
    float x = 0, y = 0, z = 0;
    cout << "Please enter two numbers you wish "
         << "to add separated by a white space:" << endl; 
    cin >> x >> y;
    z = x+y;
    cout << x << " + " << y << " = " << z << "." << endl;
    return;
}

Ответы [ 4 ]

2 голосов
/ 24 ноября 2010

Вы проверяете состояние потока:

float x, y;
if (std::cin >> x >> y) {
    // input extraction succeeded
}
else {
    // input extraction failed
}

Если это не работает для вас, вам нужно опубликовать точный код, который не работает.

1 голос
/ 25 ноября 2010

Чтобы обнаружить ошибочный ввод строки, где вы ожидали число, C ++ автоматически не знает, что вы хотите, поэтому одним из решений является сначала принять ваш ввод как строки, проверить эти строки, затем, если они действительны, только затем преобразовать строки вчисла с плавающей запятой с использованием функции atof ().

В стандартном классе строк есть функция find_first_not_of (), которая помогает вам сообщить C ++, какие символы вы считаете допустимыми.Если функция находит символ, которого нет в вашем списке, она возвращает позицию плохого символа, в противном случае возвращается строка :: npos.

// add.cpp

#include <iostream>
#include <string>
#include <cstdlib>    // for atof()

using namespace std;


void Add()
{
    cout << "Please enter two numbers you wish "
         << "to add, separated by a white space:"
         << endl;

    string num1, num2;

    cin >> num1;
    if( num1.find_first_not_of("1234567890.-") != string::npos )
    {
        cout << "invalid number: " << num1 << endl;
        return;
    }

    cin >> num2;
    if( num2.find_first_not_of("1234567890.-") != string::npos )
    {
        cout << "invalid number: " << num2 << endl;
        return;
    }

    float x = 0, y = 0, z = 0;
    x = atof( num1.c_str() );
    y = atof( num2.c_str() );
    z = x+y;

    cout << x << " + " << y << " = " << z << "." << endl;
}

int main(void)
{
    Add();
    return 0;
}
0 голосов
/ 25 ноября 2010

Другой идеей было бы проверить входные данные с регулярным выражением.Примером регулярного выражения для числа с плавающей запятой может быть

-?[0-9]+([.][0-9]+)?

. Этот метод также упростил бы уточнение механизма сопоставления, только изменив регулярное выражение, и вы могли бы сопоставить несколько регулярных выражений с различными типами ввода, напримерцелое число может быть затем выражено как

-?[0-9]+

и так далее.Имейте в виду, однако, что это только проверяет, является ли ввод действительным форматом, он все еще требует числового преобразования впоследствии (я предпочитаю boost :: lexical_cast).

(Вы также можете попробовать это с http://gskinner.com/RegExr/)

0 голосов
/ 24 ноября 2010

Одной из возможностей будет считывание ввода в виде строки, а затем использование boost lexical_cast для преобразования в число с плавающей запятой.lexical_cast считает преобразование успешным только в том случае, если вход whole преобразуется в целевой объект, в противном случае будет выдано исключение bad_lexical_cast.

...