Проблема заключается в том, что последовательность символов 2.5
четко начинается с действительного целого числа, то есть с 2
. Это то, что поток успешно читает. Таким образом, после чтения 2
нет причин для отказа потока.
Один из способов решения проблемы состоит в том, чтобы прочитать целое число, и если это успешно проверит символ, который заставил операцию чтения остановить: если этот символ является подходящим разделителем, например, пробелом, то конец файл и т.д., вы считаете, вход, чтобы быть успешным:
bool is_integer_separator(int value) {
return value == std::char_traits<char>::eof() // at the end of the file
|| value == ',' // accept comma as separator
|| std::isspace(static_cast<unsigned char>(value)); // ... and space
}
// ...
int value;
if (std::cin >> value && is_integer_separator(std::cin.peek())) {
...
}
else {
std::cout << "Not an integer\n";
}
в общем, чтение целое и останавливается, когда персонаж встречается, который не устраивает целое число является искомым определение успеха. Если вам нужно наиболее настраиваемое определение, вы можете создать его из этой функции в сочетании с тем, что будет дальше в потоке. Член std::istream::peek()
смотрит на следующего персонажа, не извлекая его. Он возвращает std::char_traits<char>::eof()
, если произошел сбой, например, поток находился в режиме отказа (то есть он установил или std::ios_base::badbit
) или был достигнут конец файла. Поскольку поток был ОК непосредственно перед этой операцией, единственный возможный сбой достиг конца файла. Затем вы можете рассмотреть, какой характер встречается и определить, хотите ли вы его принять. В примере рассматриваются пробелы и ','
как жизнеспособные разделители. Обратите внимание, что следующий символ еще не извлечен, т. Е. Вы можете избавиться от него, используя, например, std::cin.ignore()
.