简体   繁体   English

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

[英]How do I convert a double into a string in C++?

I need to store a double as a string.我需要将双精度存储为字符串。 I know I can use printf if I wanted to display it, but I just want to store it in a string variable so that I can store it in a map later (as the value , not the key ).我知道如果我想显示它,我可以使用printf ,但我只想将它存储在一个字符串变量中,以便以后可以将它存储在 map 中(作为value ,而不是key )。

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

The boost (tm) way: boost(tm)方式:

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

The Standard C++ way: 标准C ++方式:

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

Note : Don't forget #include <sstream> 注意 :不要忘记#include <sstream>

The Standard C++11 way (if you don't care about the output format): 标准C ++ 11方式(如果你不关心输出格式):

#include <string>

auto str = std::to_string(42.5); 

to_string is a new library function introduced in N1803 (r0), N1982 (r1) and N2408 (r2) " Simple Numeric Access ". to_stringN1803 (r0), N1982 (r1)和N2408 (r2)“ 简单数字访问 ”中引入的新库函数。 There are also the stod function to perform the reverse operation. 还有用于执行反向操作的stod功能。

If you do want to have a different output format than "%f" , use the snprintf or ostringstream methods as illustrated in other answers. 如果您确实希望使用与"%f"不同的输出格式,请使用其他答案中所示的snprintfostringstream方法。

If you use C++, avoid sprintf . 如果您使用C ++,请避免使用sprintf It's un-C++y and has several problems. 这是un-C ++ y并且有几个问题。 Stringstreams are the method of choice, preferably encapsulated as in Boost.LexicalCast which can be done quite easily: Stringstreams是首选方法,最好封装在Boost.LexicalCast中 ,可以很容易地完成:

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

Usage: 用法:

string s = to_string(42.5);

You can use std::to_string in C++11 您可以在C ++ 11中使用std :: to_string

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

I would look at the C++ String Toolkit Libary . 我会看一下C ++ String Toolkit Libary Just posted a similar answer elsewhere. 刚刚在别处发布了类似的答案。 I have found it very fast and reliable. 我发现它非常快速可靠。

#include <strtk.hpp>

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

sprintf is okay, but in C++, the better, safer, and also slightly slower way of doing the conversion is with stringstream : sprintf没问题,但在C ++中,更好,更安全,也更慢一点的转换方式是使用stringstream

#include <sstream>
#include <string>

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

You can also use Boost.LexicalCast : 您还可以使用Boost.LexicalCast

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

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

In both instances, str should be "453.23" afterward. 在这两种情况下, str都应该是"453.23" LexicalCast has some advantages in that it ensures the transformation is complete. LexicalCast具有一些优势,可确保转换完成。 It uses stringstream s internally. 它在内部使用stringstream

Herb Sutter has an excellent article on string formatting . Herb Sutter有一篇关于字符串格式的优秀文章 I recommend reading it. 我建议阅读它。 I've linked it before on SO. 我以前把它联系起来了

The problem with lexical_cast is the inability to define precision. lexical_cast的问题是无法定义精度。 Normally if you are converting a double to a string, it is because you want to print it out. 通常,如果要将double转换为字符串,那是因为您要将其打印出来。 If the precision is too much or too little, it would affect your output. 如果精度太高或太小,都会影响输出。

你也可以使用stringstream

Heh, I just wrote this (unrelated to this question): 嘿,我刚刚写了这个(与这个问题无关):

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

/* rest of the code */

看看sprintf()和家人。

You may want to read my prior posting on SO. 您可能想要阅读我之前发布的SO。 (Macro'ed version with a temporary ostringstream object.) (带有临时ostringstream对象的Macro'ed版本。)

For the record: In my own code, I favor snprintf(). 对于记录:在我自己的代码中,我赞成snprintf()。 With a char array on the local stack, it's not that inefficient. 使用本地堆栈上的char数组,效率并不高。 (Well, maybe if you exceeded the array size and looped to do it twice...) (好吧,也许如果你超过了数组大小并循环执行两次......)

(I've also wrapped it via vsnprintf(). But that costs me some type checking. Yelp if you want the code...) (我也通过vsnprintf()包装它。但是这需要我进行一些类型检查。如果你想要代码那么Yelp ......)

Normaly for this operations you have to use the ecvt, fcvt or gcvt Functions: Normaly对于此操作,您必须使用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   

As a Function: 作为一个功能:

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

Note that a string is just a representation of the double and converting it back to double may not result in the same value.请注意,字符串只是双精度的表示,将其转换回双精度可能不会产生相同的值。 Also note that the default string conversion may trim the conversion to a certain precision.另请注意,默认字符串转换可能会将转换修剪到一定的精度。 In the standard C++ way, you can control the precision as follows:在标准的 C++ 方式中,您可以控制精度如下:

#include <sstream>
#include <math.h>
#include <iostream>
#include <iomanip>

int main()
{
    std::ostringstream sout;
    sout << M_PI << '\n';
    sout << std::setprecision(99) << M_PI << '\n';
    sout << std::setprecision(3) << M_PI << '\n';
    sout << std::fixed; //now the setprecision() value will look at the decimal part only.
    sout << std::setprecision(3) << M_PI << '\n';
    std::cout << sout.str();
}

which will give you the output这会给你 output

3.14159                                                                                                                                                                            
3.141592653589793115997963468544185161590576171875                                                                                                                                 
3.14                                                                                                                                                                               
3.142  

You could try a more compact style: 您可以尝试更紧凑的风格:

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

Use to_string() . 使用to_string()
example : 例如:

#include <iostream>   
#include <string>  

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

  return 0;
}

run it yourself : http://ideone.com/7ejfaU 自己动手: http//ideone.com/7ejfaU
These are available as well : 这些也是可用的:

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

You can convert any thing to anything using this function: 你可以使用这个函数将任何东西转换成任何东西:

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

usage : 用法:

std::string str = to(2.5);
double d = to<double>("2.5");

C++17 has introduced: std::to_chars, std::to_chars_result - cppreference.com C++17 介绍了: std::to_chars, std::to_chars_result - cppreference.com

 std::to_chars_result to_chars( char* first, char* last, float value, std::chars_format fmt, int precision ); std::to_chars_result to_chars( char* first, char* last, double value, std::chars_format fmt, int precision ); std::to_chars_result to_chars( char* first, char* last, long double value, std::chars_format fmt, int precision );

Which provide fast low level way to convert floating points into string with some level of format control.它提供了快速的低级方法来将浮点数转换为具有某种级别格式控制的字符串。 This should be fast since no allocation is done, only custom implementation for specific scenario should be faster.这应该很快,因为没有完成分配,只有特定场景的自定义实现应该更快。

C++20 has introduced high level easy to use format string (equivalent of fmt library): C++20 引入了高级易用的格式字符串(相当于 fmt 库):

std::format - cppreference.com std::format - cppreference.com

std::format标准::格式

template< class... Args > std::string format( /*format_string<Args...>*/ fmt, Args&&... args ); template< class... Args > std::wstring format( /*wformat_string<Args...>*/ fmt, Args&&... args ); template< class... Args > std::string format( const std::locale& loc, /*format_string<Args...>*/ fmt, Args&&... args ); template< class... Args > std::wstring format( const std::locale& loc, /*wformat_string<Args...>*/ fmt, Args&&... args );

Which is quite nice and handy.这是非常好的和方便的。 Should be faster then sprintf .应该比sprintf更快。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM