Как проверить числовой ввод C ++ - PullRequest
6 голосов
/ 05 февраля 2009

Я хотел бы знать, как ограничить входное значение знаковыми десятичными знаками, используя std::cin.

Ответы [ 7 ]

11 голосов
/ 05 февраля 2009

Если вспомогательная переменная cin является числом, а предоставленная строка не является числом, возвращаемое значение равно false, поэтому вам необходим цикл:

int someVal;

while(!(cin >> someVal)) {
   cin.reset();
   cout << "Invalid value, try again.";
}
3 голосов
/ 05 февраля 2009
double i;

//Reading the value
cin >> i;

//Numeric input validation
if(!cin.eof())
{
    peeked = cin.peek();
    if(peeked == 10 && cin.good())
    {
             //Good!
             count << "i is a decimal";
        }
        else
        {
             count << "i is not a decimal";
         cin.clear();
         cin >> discard;
        }
}

Это также дает сообщение об ошибке со входом -1a2.0, избегая назначения только -1 для i.

1 голос
/ 26 декабря 2011

Сочетая приемы из верхнего ответа здесь и этого сайта, я получаю

input.h

#include <ios>  // Provides ios_base::failure
#include <iostream>  // Provides cin

template <typename T>
T getValidatedInput()
{
    // Get input of type T
    T result;
    cin >> result;

    // Check if the failbit has been set, meaning the beginning of the input
    // was not type T. Also make sure the result is the only thing in the input
    // stream, otherwise things like 2b would be a valid int.
    if (cin.fail() || cin.get() != '\n')
    {
        // Set the error state flag back to goodbit. If you need to get the input
        // again (e.g. this is in a while loop), this is essential. Otherwise, the
        // failbit will stay set.
        cin.clear();

        // Clear the input stream using and empty while loop.
        while (cin.get() != '\n')
            ;

        // Throw an exception. Allows the caller to handle it any way you see fit
        // (exit, ask for input again, etc.)
        throw ios_base::failure("Invalid input.");
    }

    return result;
}

Использование

inputtest.cpp

#include <cstdlib>  // Provides EXIT_SUCCESS
#include <iostream>  // Provides cout, cerr, endl

#include "input.h"  // Provides getValidatedInput<T>()

int main()
{
    using namespace std;

    int input;

    while (true)
    {
        cout << "Enter an integer: ";

        try
        {
            input = getValidatedInput<int>();
        }
        catch (exception e)
        {
            cerr << e.what() << endl;
            continue;
        }

        break;
    }

    cout << "You entered: " << input << endl;

    return EXIT_SUCCESS;
}

Пример прогона

Введите целое число: a
Неверный ввод.
Введите целое число: 2b
Неверный ввод.
Введите целое число: 3
Вы ввели: 3.

1 голос
/ 06 февраля 2009

Оператор cin >> работает, считывая по одному символу за раз, пока не достигнет пробела Это изменит всю строку -1a2.0, которая, очевидно, не является числом, поэтому операция завершается неудачно. Похоже, у вас есть три поля: -1, a и 2.0. Если вы разделите данные по пробелам, cin сможет прочитать все без проблем. Просто не забудьте прочитать char для второго поля.

0 голосов
/ 10 октября 2011

Я испробовал много методов для чтения целочисленного ввода от пользователя с помощью оператора >>, но так или иначе все мои эксперименты провалились.

Теперь я думаю, что функция getline() (а не метод с тем же именем на std::istream) и функция strtol() из include cstdlib - единственное предсказуемое непротиворечивое решение для этой проблемы. Буду признателен, если кто-то докажет, что я неправ. Вот что-то вроде того, что я использую:

#include <iostream>
#include <cstdlib>

// @arg prompt The question to ask. Will be used again on failure.
int GetInt(const char* prompt = "? ")
{
    using namespace std; // *1
    while(true)
    {
        cout << prompt;
        string s;
        getline(cin,s);
        char *endp = 0;
        int ret = strtol(s.c_str(),&endp,10);
        if(endp!=s.c_str() && !*endp)
            return ret;
    }
}
  • * 1: Размещение using namespace whatever; в глобальном масштабе может привести к нарушению "единства сборки" (google!) В более крупных проектах, поэтому его следует избегать. Практика, чтобы не использовать это, даже на небольших проектах!
  • Чтение целых чисел из файлов - это совсем другое дело. Подход Рауля Роа может быть полезен для этого, если его правильно проработать. Я также предлагаю не допускать неправильных входных файлов, но это действительно зависит от приложения.
  • Имейте в виду, что использование >> и getline() в одной и той же программе на cin приведет к некоторым проблемам. Используйте только один из них или Google, чтобы узнать, как решить проблему (не слишком сложно).
0 голосов
/ 09 октября 2011

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

Пожалуйста, обратитесь к: Мое решение для проверки ввода

0 голосов
/ 05 февраля 2009

Что-то вроде:

double a;
cin >> a;

Следует прочитать ваш подписанный "десятичный" штраф.

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

Удачи!

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