使用stringstream读取浮点值时出现奇怪的故障 我有下面的简单代码,它使用C++ StrugSuth读取浮点值(double)。我使用stringstream::good来检测读取是否成功。奇怪的是,该值被读入浮点变量,但good()返回false。底部的代码返回: failed: 3.14159
我在mingw32下使用gcc4.8.1编译了代码,使用使用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 >>
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;
}