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

问题描述 投票:0回答:19

我需要将双精度值存储为字符串。我知道如果我想显示它,我可以使用

printf
,但我只想将其存储在字符串变量中,以便稍后可以将其存储在地图中(作为 value,而不是 key)。

c++ string double
19个回答
234
投票
// 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);

198
投票

boost (tm)方式:

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

标准 C++ 方式:

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

注意:别忘了

#include <sstream>


146
投票

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

#include <string>

auto str = std::to_string(42.5); 

to_string
N1803 (r0)、N1982 (r1) 和 N2408 (r2)“简单数字访问”中引入的新库函数。还有
stod
功能可以进行反向操作。

如果您确实想要使用与

"%f"
不同的输出格式,请使用
snprintf
ostringstream
方法,如其他答案中所示。


32
投票

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

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

24
投票

如果您使用 C++,请避免

sprintf
。它不是 C++ 的,并且有几个问题。 Stringstreams 是首选方法,最好封装在 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);

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


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
投票

您还可以使用stringstream


4
投票

呵呵,我刚刚写了这个(与这个问题无关):

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

/* rest of the code */

4
投票

通常对于此操作,您必须使用 C 默认的 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);
}

2
投票

您可能想阅读我之前关于 SO 的帖子。 (带有临时 ostringstream 对象的宏版本。)

郑重声明:在我自己的代码中,我更喜欢 snprintf()。使用本地堆栈上的 char 数组,效率并没有那么低。 (好吧,也许如果你超出了数组大小并循环执行两次......)

(我还通过 vsnprintf() 包装了它。但这需要我进行一些类型检查。如果你想要代码,请大声喊...)


2
投票

看看

sprintf()
和家人。


2
投票

请注意,字符串只是 double 的表示形式,将其转换回 double 可能不会产生相同的值。 另请注意,默认字符串转换可能会将转换修剪为一定的精度。 在标准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();
}

这会给你输出

3.14159                                                                                                                                                                            
3.141592653589793115997963468544185161590576171875                                                                                                                                 
3.14                                                                                                                                                                               
3.142  

1
投票

使用

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
投票

你可以尝试更紧凑的风格:

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
投票

您可以使用此功能将任何东西转换为任何东西:

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

0
投票

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

它提供了快速的低级方法将浮点转换为具有某种格式控制级别的字符串。这应该很快,因为没有完成分配,只有特定场景的自定义实现应该更快。

C++20 引入了高级易于使用的格式字符串(相当于 fmt 库):

std::格式 - cppreference.com

std::格式

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

这非常好用且方便。应该会更快

sprintf


0
投票

double
转换为字符串的最简单方法是通过
std::to_string
,但不幸的是,它在 C++20 中已经被分解,并且 可能只能在 C++26 中修复。

std::to_string
修复之前,您可以使用 C++20
std::format
,例如

std::string s = std::format("{}", 0.42);

免责声明:我是 C++20 的作者

std::format

© www.soinside.com 2019 - 2024. All rights reserved.