如何在C ++中将双精度型转换为字符串?


171

我需要将双精度字存储为字符串。我知道可以printf显示它,但我只想将其存储在字符串变量中,以便以后可以将其存储在地图中(作为value,而不是key)。


2
一个回答您问题的问题:为什么将双精度值存储在字符串中以将其存储在地图中?您将使用字符串化的double作为关键字吗?如果没有,为什么不保留原样?
马特·麦克莱伦

1
有趣的一点。但是,使用双精度键作为映射键可能会带来危险,因为对浮点值的精确比较总是如此。在字符串表示形式上建立索引可以避免此问题。
Fred Larson

2
为什么要全部转换?将其作为双倍存储在地图中,并避免与之进行转换。
EvilTeach

3
听起来仍然像是对对象的呼吁。工会会起作用。每个对象都可以在其中插入各种值,并对其进行自我验证。
EvilTeach

2
我的文件中只有一堆名称/值对。它不要求对象。
比尔蜥蜴

Answers:


183

升压(TM)方式:

std::string str = boost::lexical_cast<std::string>(dbl);

标准C ++方式:

std::ostringstream strs;
strs << dbl;
std::string str = strs.str();

注意:别忘了#include <sstream>


3
我认为boost :: lexical_cast几乎是标准的C ++方式,为您打包的很好。顺便说一句,litb,您在这里有一个较小的错字-“ boot:lexical_cast”。
Fred Larson

2
boost :: lexical_cast不仅仅是围绕stringstream代码的简单包装。许多转换例程是内联实现的。根据此页面底部的性能度量(boost.org/doc/libs/1_47_0/libs/conversion/lexical_cast.htm),boost :: lexical_cast比使用字符串流更快,并且在大多数情况下,比scanf / printf
Ferruccio

1
@Ferr谁说这是一个简单的包装?感谢您提供链接,实际上我确实认为它或多或少是一个简单的包装器:)
Johannes Schaub-litb 2011年

27
不要忘记#include <sstream>使用c ++方式:)
VladL 2013年

3
出于文档目的,如果不这样做#include <sstream>,则会收到错误消息“不允许输入不完整的类型”。
Trevor Sullivan 2014年

194
// The C way:
char buffer[32];
snprintf(buffer, sizeof(buffer), "%g", myDoubleVar);

// The C++03 way:
std::ostringstream sstream;
sstream << myDoubleVar;
std::string varAsString = sstream.str();

// The C++11 way:
std::string varAsString = std::to_string(myDoubleVar);

// The boost way:
std::string varAsString = boost::lexical_cast<std::string>(myDoubleVar);

1
您的C ++方式无效,因为operator <<返回std::ostream&而不是stringstream&
康拉德·鲁道夫

看来我的字符串流有些生疏,我更喜欢C语言方式。现在修复(我希望)。
亚当·罗森菲尔德

您的C代码起初使我失望。我仍然支持您提供正确的选择。
蜥蜴比尔

2
赞成包括C方式。对我来说似乎更干净。
Nealon

11
支持C ++ 11方式。我是C ++的新手,但没有意识到有一个to_string函数。我正在使用Microsoft Visual C ++2013。–
Trevor Sullivan

123

标准C ++ 11的方式(如果你不关心输出格式):

#include <string>

auto str = std::to_string(42.5); 

to_string是一个新的库函数中介绍N1803(R0),N1982(r1)和N2408(r2)“ 简单数字访问 ”中。还有stod执行反向操作的功能。

如果您确实要使用不同于的输出格式"%f",请使用snprintfostringstream其他答案中说明方法。


3
哦耶宝宝。to_string和11在Visual Studio STOD都工作
BSalita

哦,亲爱的宝贝... to_string在
Visual Studio

1
这应该更高,因为它更现代!
gsamaras

1
有什么方法可以使此函数不增加超出所需的小数位数?当我转换为double时,8.0它会给我字符串"8.000000",而"8"这会很好。
HelloGoodbye 2015年

1
这不适用于小数字...例如:1e-9产生0.000000
user3728501

24

如果使用C ++,请避免使用sprintf。它不是C ++ y,并且有几个问题。字符串流是一种选择的方法,最好像Boost.LexicalCast中那样封装,可以很容易地完成:

template <typename T>
std::string to_string(T const& value) {
    stringstream sstr;
    sstr << value;
    return sstr.str();
}

用法:

string s = to_string(42.5);

24

您可以在C ++ 11中使用std :: to_string

double d = 3.0;
std::string str = std::to_string(d);

我的数字很小,std::to_string()仅返回了0.000000,而不是科学形式。
erfan

11

sprintf可以,但是在C ++中,转换的更好,更安全,也稍慢的方法是stringstream

#include <sstream>
#include <string>

// In some function:
double d = 453.23;
std::ostringstream os;
os << d;
std::string str = os.str();

您还可以使用Boost.LexicalCast

#include <boost/lexical_cast.hpp>
#include <string>

// In some function:
double d = 453.23;
std::string str = boost::lexical_cast<string>(d);

在这两种情况下,str都应该"453.23"事后进行。LexicalCast具有一些优势,因为它可以确保转换完成。它stringstream在内部使用s。


10

我将看一下C ++ String Toolkit Libary。刚刚在其他地方发布了类似的答案。我发现它非常快速可靠。

#include <strtk.hpp>

double pi = M_PI;
std::string pi_as_string  = strtk::type_to_string<double>( pi );


6

lexical_cast的问题是无法定义精度。通常,如果要将双精度型转换为字符串,这是因为要打印出来。如果精度太大或太小,都会影响输出。



4

呵呵,我只是写了这个(与此问题无关):

string temp = "";
stringstream outStream;
double ratio = (currentImage->width*1.0f)/currentImage->height;
outStream << " R: " << ratio;
temp = outStream.str();

/* rest of the code */


2

sprintf()和家人一起看看。


2
我之所以提到printf,是因为谷歌搜索出现了很多文章,这些文章说您可以使用printf将双精度型转换为字符串。他们假设您唯一可以做的就是打印,在我看来,这是错误的。
比尔蜥蜴,

你为什么投票-1?我认为sprintf很好。@BilltheLizard,sprint将某些内容打印到char *而不是屏幕上。有人回答c方法仍然获得了很多选票。
worldterminator 2015年

2

通常,对于此操作,您必须使用ecvt,fcvt或gcvt函数:

/* gcvt example */
#include <stdio.h>
#include <stdlib.h>

main ()
{
  char buffer [20];
  gcvt (1365.249,6,buffer);
  puts (buffer);
  gcvt (1365.249,3,buffer);
  puts (buffer);
  return 0;
}

Output:
1365.25
1.37e+003   

作为功​​能:

void double_to_char(double f,char * buffer){
  gcvt(f,10,buffer);
}

0

您可以尝试更紧凑的样式:

std::string number_in_string;

double number_in_double;

std::ostringstream output;

number_in_string = (dynamic_cast< std::ostringstream*>(&(output << number_in_double <<

std::endl)))->str(); 

0

使用to_string()
例如:

#include <iostream>   
#include <string>  

using namespace std;
int main ()
{
    string pi = "pi is " + to_string(3.1415926);
    cout<< "pi = "<< pi << endl;

  return 0;
}

自己运行它:http : //ideone.com/7ejfaU
这些也可用:

string to_string (int val);
string to_string (long val);
string to_string (long long val);
string to_string (unsigned val);
string to_string (unsigned long val);
string to_string (unsigned long long val);
string to_string (float val);
string to_string (double val);
string to_string (long double val);

0

您可以使用此功能将任何事物转换为任何事物:

template<class T = std::string, class U>
T to(U a) {
    std::stringstream ss;
    T ret;
    ss << a;
    ss >> ret;
    return ret;
};

用法:

std::string str = to(2.5);
double d = to<double>("2.5");
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.