В следующем примере я не ожидал, что 1.2345foo
будет проанализирован. Поскольку я читаю файлы данных, вероятно, лучше выдать ошибку и уведомить пользователя.
Является peek()
правильная вещь здесь?
#include <iostream>
#include <sstream>
int main()
{
std::stringstream in("1.2345foo");
double x;
in >> x;
if (in) {
std::cout << "good\n";
}
else {
std::cout << "bad\n";
}
}
Выход
good
Просто посмотрите вперед на следующего персонажа. В случае
изолированный std::istringstream
Вы можете сделать что-то вроде:
if ( in >> x && in.get() == std::string::traits_type::eof() ) {
// good
} else {
// bad
}
(Я обычно люблю разделять тесты, чтобы дать больше
содержательные сообщения об ошибках.)
Если вы заинтересованы в данных в большем файле, где для
пример "1.2345 foo"
было бы законно, но "1.2345foo"
не,
Вы можете использовать прогнозирование, что-то вроде:
if ( in >> x
&& (std::isspace( in.peek() )
|| in.peek() == std::string::traits_type::eof()) ) {
// good
} else {
// bad
}
РЕДАКТИРОВАТЬ:
Я забыл упомянуть: в первом случае вы можете пропустить
пустое пространство перед проверкой на eof:
if ( in >> x >> std::ws && in.get() == std::string::traits_type::eof() ) ...
(Я делаю это много. Если строка ввода из std::getline
,
Вы действительно хотите разрешить конечный пробел, так как это
невидимым для всех, кто смотрит на файл.)
Самый простой способ прочитать это как std::string
, а затем использовать std::stod
преобразовать std::string
в double
, Функция преобразования выдаст исключение для неверного ввода, например, когда вы передаете "1.2345foo"
к этому.