使用stringstream读取浮点值时出现奇怪的故障 我有下面的简单代码,它使用C++ StrugSuth读取浮点值(double)。我使用stringstream::good来检测读取是否成功。奇怪的是,该值被读入浮点变量,但good()返回false。底部的代码返回: failed: 3.14159

使用stringstream读取浮点值时出现奇怪的故障 我有下面的简单代码,它使用C++ StrugSuth读取浮点值(double)。我使用stringstream::good来检测读取是否成功。奇怪的是,该值被读入浮点变量,但good()返回false。底部的代码返回: failed: 3.14159,c++,c++11,stringstream,C++,C++11,Stringstream,我在mingw32下使用gcc4.8.1编译了代码,使用g++-std=c++11 test.cpp 你知道为什么这个读数不好吗?那么,正确的方法是什么来判断浮点值实际上是成功读取的呢 谢谢 #include <sstream> #include <iostream> using namespace std; void readFloat(string s) { double i = 0!; stringstream ss(s); ss >>

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

你知道为什么这个读数不好吗?那么,正确的方法是什么来判断浮点值实际上是成功读取的呢

谢谢

#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");
}
#包括
#包括
使用名称空间std;
void readFloat(字符串s){
双i=0!;
溪流ss(s);;
ss>>i;
如果(ss.good())

这里没有奇怪的行为吗

如果已到达文件末尾,则函数返回false,情况就是这样。 如果你在“ss>>i”之前测试好,我相信它会返回真值

测试的一个好方法是:

  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");

当流在提取过程中到达流的末尾时,它们将
std::ios_base::eofbit设置为流状态,以提醒用户无法读取更多字符。这意味着
good()
在清除流状态之前不再返回true

通常,
good()
不是确定I/O成功的可靠方法。
good()
作为一种条件,意味着每一位(包括
eofbit
)未设置,如果您只是试图确定I/O操作是否成功,则可能会产生误导。因为设置了
eofbit
,所以您的程序会告诉您I/O操作失败,而它没有成功

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

if(ss>>i){

std::读取是否命中了EOF字符,因此设置了
EOF()
。我不相信g++允许
main()
没有返回类型声明。真正的代码是什么?这是实际的代码复制粘贴。哇,没想到GCC会接受。不过,打开警告(-Wall)然后,它给出了<代码>警告:ISO C++禁止声明“主”,没有类型< /COD>。“TingL有没有帮助这些答案?如果可以,你可以通过点击他们旁边的复选标记来接受其中一个。它向社区表达你找到了一个可接受的答案。试试空字符串作为输入。”请检查<代码>。boost::lexical_cast
要获得正确的方法,请使用
运行时错误
。感谢您的明确解释。这是否意味着检查读取是否成功(不管其他任何情况)的正确方法是测试
(!ss.fail())
?有什么陷阱吗?@TingL没有,这不是正确的方法(通常):新用户经常犯错误,在(!o.fail())
while(!o.eof())
时使用
作为循环的条件,而此时应该是
while(*I/o操作*)
而不是像我上面所做的那样。前者在执行输入之前检查流状态,这是不正确的,因为它允许您使用失败提取的结果。除非必须使用,否则不要显式使用
fail()
。在这种情况下,您不需要。请澄清,使用(!o.fail())是否仍然可以在输入之后?在我的情况下,用(!o.fail())替换o.good()。有什么潜在的问题吗?我有点担心在条件中混合副作用,如果可能的话,我希望避免这种风格。@TingL在输入之后直接检查
fail()
没有问题。但是,对于你的
do{}while(!o.fail())
循环,这仍然是不正确的。这不仅会导致额外的循环,还将使用失败提取的结果(如果使用较新的编译器,可能会导致未定义的行为)。更习惯于在(is>>x)
时简单地执行
;这就是设计使用流的方式。
if (ss >> i) {
    std::cout << "read: " << i << std::endl;
}
else {
    std::cout << "failed: " << i << std::endl;
}