2

在下面的例子中,我没想到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
4

2 回答 2

2

最简单的方法是把它读成std::string,然后用它std::stod来转换std::stringdouble. 转换函数将为无效输入抛出异常,例如当您传递"1.2345foo"给它时。

于 2012-11-20T17:01:09.790 回答
2

只需向前看下一个字符。在孤立的情况下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() ) ...

(我经常这样做。如果字符串输入是 from std::getline,您确实希望允许尾随空格,因为任何查看文件的人都看不到它。)

于 2012-11-20T18:34:30.717 回答