Я пишу программу, где я должен проверить, что введенное значение пользователем является допустимым числом с плавающей запятой. Итак, я пробовал этот метод:
string test;
cin >> test;
float n;
n = atof(test.c_str());
cout << n << endl;
Но, похоже, это не делает работу; когда он выполняет преобразование, числа после .
потеряны. Как я могу проверить, что допустимый номер с плавающей запятой используется в C++ (не 11)?
Примеры:
INPUT: 32.e
OUTPUT: 32 (should be error)
INPUT: 2a.1234
OUTPUT: 2 (should be error)
Когда вы используете форматированные чтения в сочетании с проверкой, читается ли все, вы можете определить, является ли значение [complete] допустимым числом с плавающей запятой, например:
int main()
{
for (std::string test; std::cin >> test; ) {
std::istringstream in(test);
double value;
if (in >> value >> std::ws && in.eof()) {
std::cout << "the string '" << test << "' is a valid floating point number\n";
}
else {
std::cout << "the string '" << test << "' is not a valid floating point number\n";
}
}
}
Тест игнорирует пробелы, окружающие строку. Если это нежелательно, можно использовать манипулятор std::noskipws
, и использование std::ws
может быть опущено. В качестве альтернативы вы можете использовать strtod()
чтобы определить, является ли все значение числом с плавающей запятой.
Какой atof()
должен просто увидеть, является ли исходная строка его аргумента допустимым числом с плавающей запятой, которое имеет место для примеров, которые вы указали.
int main() {
float f;
cin >> f;
if (!cin.fail()) {
cout << f << endl;
} else {
cout << "Invalid input" << endl;
}
// your code goes here
return 0;
}
Функция fail()
проверяет failbit
и badbit
в потоке. сигналы failbit
что вы хотите, если была логическая ошибка при операции ввода-вывода (пример: попытаться прочитать поплавок, но не смог разобрать токен для поплавка) и сигналы badbit
если была ошибка чтения/записи на i/o (не умеет читать/записывать токен вообще).
Ответ действительно зависит от того, хотите ли вы проверить всю строку ввода. atof будет работать, даже если только начало ввода является поплавком (например, 3.3a, 4.72abc). Если вы хотите, чтобы весь входной поток был проверен, вам придется использовать getline для чтения строки и ее анализа. Просто проверьте наличие только цифр плюс один ".".
Я благодарю C++ faq lite за основную идею. http://www.parashift.com/C++-faq/istream-and-ignore.html
Мой пример находится в цикле, так что вы можете более легко понять, что я имею в виду.
#include <iostream>
#include <limits>
int main()
{
while(true)
{
double value = 0;
while ((std::cout << "Enter a floating point number\n ")
&& !(std::cin >> value)) {
std::cout << "\nThat not a floating point number\n ";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
std::cout << "You entered " << value << "\n";
}
return 0;
}
double
константой в большинстве систем. То есть вам нужно учесть знаки, а может быть и показатели. И это еще до того, как вы начнете учитывать шестнадцатеричные константы.
strtod()
(из<cstdlib>
или более<cstdlib>
на C ++ альтернативы), чтобы выполнить преобразование. Учитывая адрес подходящего указателя на char,strtod()
также сообщает, где он прекратит преобразование. Вы можете решить, хотите ли вы возражать против того, что появляется после этого (например, разрешены ли пробелы, табуляции, новые строки).