如何从字符串流中提取双精度

How to extract double from a stringstream

本文关键字:提取 双精度 字符串      更新时间:2023-10-16

在处理我的C++项目时,我在玩stringstream对象时注意到一些奇怪的东西:我无法使用>>stringstream中提取double

请考虑以下示例:

#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数字文本放入变量时,将设置字符串流的故障位,并且对字符串流提取的后续调用也会失败。一个好方法是在使用流 IO 时使用if语句:

if (stringstream >> integer >> character){
// success
}

快速演示来强化罗恩的答案:(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;
}

示例输出(iMac 64 位(:

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