Как проверить числовой ввод C++
Я хотел бы знать, как ограничить входное значение знаковыми десятичными знаками, используя std::cin
.
7 ответов
Если переменная поддержки cin
- это число, а строка не является числом, возвращаемое значение равно false, поэтому вам нужен цикл:
int someVal;
while(!(cin >> someVal)) {
cin.reset();
cout << "Invalid value, try again.";
}
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.
оператор cin >> работает, читая по одному символу за раз, пока он не попадет в пробел. Это будет хлебать всю строку -1a2.0
, что, очевидно, не является числом, поэтому операция завершается неудачей. Похоже, у вас на самом деле есть три поля: -1, a и 2.0. Если вы разделите данные пробелами, cin сможет прочитать каждый из них без проблем. Просто не забудьте прочитать char
для второго поля.
объединение методов из верхнего ответа здесь и этой веб-сайт, я получаю
вход.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.
Я не пытаюсь быть грубым. Я просто хотел поделиться решением, которое я предоставил, которое я считаю более надежным и позволяет лучше проверять ввод.
пожалуйста, обратитесь к: мое решение для проверки ввода
я пробовал много методов для чтения целочисленного ввода от пользователя с помощью >>
оператора, но так или иначе все мои эксперименты провалились.
теперь я думаю, что 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;
к глобальной области может привести к нарушению " unity builds "(google!) в более крупных проектах этого следует избегать. Практика, чтобы не использовать этот путь, даже на небольших проектах! - чтение целых чисел из файлов-это совсем другое дело. Подход Рауля Роа может быть хорош для этого, если он правильно разработан. Я также предлагаю, чтобы неправильные входные файлы не допускались, но это действительно зависит от приложения.
- предупреждаю что с помощью
>>
иgetline()
в той же программе оcin
приведет к некоторым проблемам. Используйте только один из них или google, чтобы знать, как справиться с проблемой (не слишком сложно).
что-то типа:
double a;
cin >> a;
должен прочитать ваш подписанный "десятичный" штраф.
вам понадобится цикл и некоторый код, чтобы убедиться, что он обрабатывает недопустимый ввод разумным образом.
удачи!