使用stringstream读取浮点值的奇怪失败

时间:2014-05-16 20:37:57

标签: c++ c++11 stringstream

我有以下简单的代码,它使用c ++ stringstream读取浮点值(double)。我使用stringstream :: good来检测读取是否成功。奇怪的是,该值被读入float变量,但good()返回false。底部的代码返回:

failed: 3.14159

我在mingw32下使用gcc 4.8.1编译代码,g++ -std=c++11 test.cpp

知道为什么这次阅读不是good?什么是告诉浮动实际读取成功的正确方法?

由于

#include <sstream>
#include <iostream>
using namespace std;

void readFloat(string s) {
  double i = 0!; 
  stringstream ss(s); 
  ss >> i;
  if (ss.good())
    cout << "read: " << i << endl;
  else
    cout << "failed: " << i << endl;
}

main() {
  readFloat("3.14159");
}

2 个答案:

答案 0 :(得分:3)

当流在提取期间到达流的末尾时,它们在流状态中设置std::ios_base::eofbit以警告用户不能再读取字符。这意味着在清除流状态之前good()不再返回true。

通常,good()不是确定I / O成功的可靠方法。 good()作为条件意味着未设置每个位(包括eofbit),如果您只是尝试确定I / O操作是否成功,则可能会产生误导。由于eofbit已设置,因此您的程序会告诉您I / O操作失败时会失败。

相反,最好将整个提取包装在条件中以确定它是否成功。流中将隐式转换为布尔值,流将在内部调用!this->fail(),这是good()的更好选择:

if (ss >> i) {
    std::cout << "read: " << i << std::endl;
}
else {
    std::cout << "failed: " << i << std::endl;
}

答案 1 :(得分:1)

这里没有奇怪的行为

stringstream::good()

如果到达文件的末尾,则该函数返回false,这是这种情况。 如果你在“ss&gt;&gt; i”之前测试好,我相信它会返回true。

测试的好方法是:

  double i = 0.0;
  std::stringstream ss(s); 

  if (!ss.good())
    throw std::exception("Stream not good");
  ss >> i;
  if (!ss.eof())
    throw std::exception("Stream not read entirely");