Фильтрация неверных пользовательских данных - PullRequest
1 голос
/ 06 октября 2010

Я пытаюсь отфильтровать недопустимые пользовательские вводы в небольшой программе на C ++, используя следующий фрагмент кода:

    int selection = -1;
    while (!(selection >= 1 && selection <=4))
    {   
        cin >> selection;

        if (!(selection >= 1 && selection <=4))
        {
            cout << "invalid selection!" << endl;
            cout << "selection: ";
        }
    }

Кажется, что все работает нормально, когда я ввожу любое числовое значение, которое находится внутри или вне диапазона, который я хочу отфильтровать Однако странные вещи случаются, когда я ввожу недопустимые значения, такие как значения, превышающие максимальное хранимое значение int или символы. Код перебирает и пропускает команду "cin".

Как мне это исправить?

Спасибо

Ответы [ 5 ]

4 голосов
/ 06 октября 2010

Необходимо обнаружить необратимый ввод с помощью fail(), а затем игнорировать оставшиеся неверные данные и сбросить cin флаги ошибок с помощью clear() перед чтением при новой попытке ввода.

int selection = -1;
while (!(selection >= 1 && selection <=4))
{   
    cin >> selection;

    if (cin.fail() || !(selection >= 1 && selection <=4))
    {
        cout << "invalid selection!" << endl;
        cout << "selection: ";

        cin.clear();

        cin.ignore(std::numeric_limits<int>::max(), '\n');
    }
}
4 голосов
/ 06 октября 2010

Вот два предложения по исправлению вашей проблемы:

  1. Добавить обработку ошибок в cin
  2. Читать как строку и анализировать

ОбщееРешение - «Читать как строка» и «Разбор», но я представляю оба варианта на ваш выбор.

Добавить обработку ошибок в cin

Когда функция извлечения потока получает символ, который не подходит для чисел, она устанавливает бит fail.Вам необходимо проверить состояние потока (cin) на наличие ошибок.Если вы хотите продолжить, вам нужно очистить состояние ошибки.

Состояние можно проверить с помощью метода fail: cin.fail().Для очистки состояния используйте: cin.clear().

См. Онлайн-справочник по C ++ - istream

Чтение как строка и синтаксический анализ

В качестве альтернативы читайте ввод как строку, а затем анализируйте строкудля ваших данных.Контейнер string имеет несколько полезных методов для анализа.

Используйте getline для чтения переменной string из cin.

Опять же, вам придется написать код для проверки ошибок и их обработки.

1 голос
/ 06 октября 2010

Вам необходимо проверить условие cin, и, если это какие-либо состояния ошибки, вы должны очистить флаг ошибки и ignore():

int main()
{
    int selection = -1;
    while (!(selection >= 1 && selection <=4))
    {
        if (cin >> selection)
        {
            if (!(selection >= 1 && selection <=4))
            {
                cout << "invalid selection!" << endl;
                cout << "selection: ";
            }
        }
        else
        {
            cin.clear();
            cin.ignore();
        }
    }

    cout << selection << " selected\n";

    return 0;
}

Другой способ - прочитать все как string и разрешить stringstream делать проверку ошибок:

int main()
{
    int selection = -1;
    while (!(selection >= 1 && selection <=4))
    {
        string line;
        getline(cin, line);

        stringstream sstr(line);
        if (sstr >> selection)
        {
            if (!(selection >= 1 && selection <=4))
            {
                cout << "invalid selection!" << endl;
                cout << "selection: ";
            }
        }
        else
        {
            cout << "invalid input!" << endl;
            cout << "selection: ";
        }
    }

    cout << selection << " selected\n";

    return 0;
}

Примечание: Возможно, вам потребуется поставить cin.ignore(); сразу после getline() вызова - в зависимости от того, читаете ли вы все неформатированные данные или нет.

0 голосов
/ 06 октября 2010

Вы должны прочитать cin в std :: string и начать проверку с этого момента.Проверьте, что значение является числовым, для начала.

0 голосов
/ 06 октября 2010

Например, когда вы вводите буквы, он переводит cin в плохое состояние и оставляет эти символы. Вам нужно ignore их (cin.ignore(1024, '\n')), чтобы он знал, чтобы перейти к следующей строке ввода.

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