如何从 stringstream 中提取 double
How to extract double from a stringstream
在处理我的 C++ 项目时,我注意到在使用 stringstream
对象时有些奇怪:我无法使用 [=] 从 stringstream
中提取 double
14=].
考虑这个例子:
#include <string>
#include <sstream>
int main(int argc, const char * argv[]) {
std::string string("1000 ; 523277527397538 ; 0.183 ; 0.453 ; 0.5 ; 0.5 ; 0.033 ; 0 ; 0 ;");
std::stringstream stringstream(string);
int integer;
char character;
double doubleprec;
stringstream >> integer >> character;
stringstream >> integer >> character;
stringstream >> doubleprec >> character;
stringstream >> doubleprec >> character;
return 0;
}
使用我的调试器我注意到变量 integer
首先取值 1000
然后取值 523277527397538
(如我所料),但是 doubleprec
始终取值 0
.
这是为什么?我是否遗漏了有关流如何工作的信息?
只有第一个流输出语句:
stringstream >> integer >> character;
成功。剩下的三个不是因为你的int变量装不下523277527397538
的值。将其更改为 long long
:
long long integer;
当流提取未能将 523277527397538
数字文字放入您的变量时,将设置字符串流的 failbit,随后对字符串流提取的调用也会失败。一个好的方法是在处理流 IO 时使用 if
语句:
if (stringstream >> integer >> character){
// success
}
快速演示以强化 Ron 的回答:(c++14)
#include <string>
#include <sstream>
#include <iostream>
int main(int argc, const char * argv[]) {
std::string string("1000 ; 523277527397538 ; 0.183 ; 0.453 ; 0.5 ; 0.5 ; 0.033 ; 0 ; 0 ;");
std::stringstream stringstream(string);
auto okfail = [](auto&& b) {
if (not b) return std::string("fail");
return std::string("ok");
};
auto read = [&](auto&& var, auto&& f) {
std::cout << "reading " << var << ". Stream is " << okfail(stringstream) << std::endl;
f();
std::cout << "read " << var << ". Stream is " << okfail(stringstream) << std::endl;
};
int integer1;
int integer2;
char character;
double doubleprec1, doubleprec2;
read("integer1", [&] { stringstream >> integer1 >> character; });
read("integer2", [&] { stringstream >> integer2 >> character; });
read("doubleprec1", [&] { stringstream >> doubleprec1 >> character; });
read("doubleprec2", [&] { stringstream >> doubleprec2 >> character; });
std::cout << integer1<< " " << integer2 << " " << doubleprec1 << " " << doubleprec2 << " " << std::endl;
return 0;
}
示例输出(64 位 imac):
reading integer1. Stream is ok
read integer1. Stream is ok
reading integer2. Stream is ok
read integer2. Stream is fail
reading doubleprec1. Stream is fail
read doubleprec1. Stream is fail
reading doubleprec2. Stream is fail
read doubleprec2. Stream is fail
1000 2147483647 0 0
现在将 integer2 更改为 long int:
reading integer1. Stream is ok
read integer1. Stream is ok
reading integer2. Stream is ok
read integer2. Stream is ok
reading doubleprec1. Stream is ok
read doubleprec1. Stream is ok
reading doubleprec2. Stream is ok
read doubleprec2. Stream is ok
1000 523277527397538 0.183 0.453
在处理我的 C++ 项目时,我注意到在使用 stringstream
对象时有些奇怪:我无法使用 [=] 从 stringstream
中提取 double
14=].
考虑这个例子:
#include <string>
#include <sstream>
int main(int argc, const char * argv[]) {
std::string string("1000 ; 523277527397538 ; 0.183 ; 0.453 ; 0.5 ; 0.5 ; 0.033 ; 0 ; 0 ;");
std::stringstream stringstream(string);
int integer;
char character;
double doubleprec;
stringstream >> integer >> character;
stringstream >> integer >> character;
stringstream >> doubleprec >> character;
stringstream >> doubleprec >> character;
return 0;
}
使用我的调试器我注意到变量 integer
首先取值 1000
然后取值 523277527397538
(如我所料),但是 doubleprec
始终取值 0
.
这是为什么?我是否遗漏了有关流如何工作的信息?
只有第一个流输出语句:
stringstream >> integer >> character;
成功。剩下的三个不是因为你的int变量装不下523277527397538
的值。将其更改为 long long
:
long long integer;
当流提取未能将 523277527397538
数字文字放入您的变量时,将设置字符串流的 failbit,随后对字符串流提取的调用也会失败。一个好的方法是在处理流 IO 时使用 if
语句:
if (stringstream >> integer >> character){
// success
}
快速演示以强化 Ron 的回答:(c++14)
#include <string>
#include <sstream>
#include <iostream>
int main(int argc, const char * argv[]) {
std::string string("1000 ; 523277527397538 ; 0.183 ; 0.453 ; 0.5 ; 0.5 ; 0.033 ; 0 ; 0 ;");
std::stringstream stringstream(string);
auto okfail = [](auto&& b) {
if (not b) return std::string("fail");
return std::string("ok");
};
auto read = [&](auto&& var, auto&& f) {
std::cout << "reading " << var << ". Stream is " << okfail(stringstream) << std::endl;
f();
std::cout << "read " << var << ". Stream is " << okfail(stringstream) << std::endl;
};
int integer1;
int integer2;
char character;
double doubleprec1, doubleprec2;
read("integer1", [&] { stringstream >> integer1 >> character; });
read("integer2", [&] { stringstream >> integer2 >> character; });
read("doubleprec1", [&] { stringstream >> doubleprec1 >> character; });
read("doubleprec2", [&] { stringstream >> doubleprec2 >> character; });
std::cout << integer1<< " " << integer2 << " " << doubleprec1 << " " << doubleprec2 << " " << std::endl;
return 0;
}
示例输出(64 位 imac):
reading integer1. Stream is ok
read integer1. Stream is ok
reading integer2. Stream is ok
read integer2. Stream is fail
reading doubleprec1. Stream is fail
read doubleprec1. Stream is fail
reading doubleprec2. Stream is fail
read doubleprec2. Stream is fail
1000 2147483647 0 0
现在将 integer2 更改为 long int:
reading integer1. Stream is ok
read integer1. Stream is ok
reading integer2. Stream is ok
read integer2. Stream is ok
reading doubleprec1. Stream is ok
read doubleprec1. Stream is ok
reading doubleprec2. Stream is ok
read doubleprec2. Stream is ok
1000 523277527397538 0.183 0.453