将双精度转换为字符数组 C++
Posted
技术标签:
【中文标题】将双精度转换为字符数组 C++【英文标题】:Convert double to Char Array C++ 【发布时间】:2018-06-06 00:12:37 【问题描述】:我正在尝试将 double 转换(并舍入)为 char 数组,而不首先在 double 上使用 std::to_string 进行转换。但是,我收到的是随机记忆文本。我究竟做错了什么?
这是我的代码:
double d = 1.0929998;
d = std::round(d * 100) / 100;
char s[sizeof(d)];
std::memcpy(s,&d,sizeof(d));
结果:
s: q=×£pñ?
预期值:
s: 1.09
【问题讨论】:
使用to_string
有什么问题?
A double
不是 char
的数组。如果就这么简单,就不需要std::to_string
。将浮点值转换为文本字符串涉及大量工作。对于更简单的问题,尝试将int
值转换为字符串。一旦你完成了这项工作,你就可以开始考虑浮点转换。或者您可以只使用内置的库设施。上次我写了一个浮点到文本的转换函数,花了好几个星期。这不是初学者的任务。
如果std::to_string
如此可恶,也许像sprintf
这样的C API 可以满足您的需求?
您可能会发现不想使用 sprintf 的人对这个问题的回答很有趣。几乎做了一些数学运算来获得幅度,然后通过重复除法一次获得一个数字来表示字符串。 ***.com/questions/2302969/convert-a-float-to-a-string
【参考方案1】:
您正在将double
的文字字节翻译成char
s。 double
值是二进制表示(通常类似于IEEE 754),而char
是字符的二进制表示(通常基于ASCII)。这两个不兼容。
不幸的是,这意味着您必须进行某种转换过程。要么是你说不想做的std::to_string()
,要么是更复杂的std::stringbuf
(无论如何都会在后台调用std::to_string()
)
【讨论】:
所以我在看类似的东西:double d = 1.0909998; d = std::round(d * 100) / 100;字符 [4]; std::strncpy(s,std::to_string(d).c_str(), 4);对于带有舍入截断的双重转换? @Delrog 我建议使用snprintf
而不是strncpy
+to_string
您可以让 STL 为您进行舍入。使用std::ostringstream
,查看std::fixed
和std::setprecision()
流操作符,例如:ostringstream oss; oss << fixed << setprecision(3) << d; string s = oss.str();
谢谢,我通常会尽量避开字符串流,因为我认为它们会带来开销。他们有吗?有没有办法一目了然地确定标准库函数的内存/性能成本(cppreference 或替代文档)?【参考方案2】:
您正在将double
(数字的二进制表示)复制到char
数组中;没有理由这些字节应该对应于数字字符。
【讨论】:
【参考方案3】:这未经测试,但您可以尝试:
std::string to_string(double x)
std::ostringstream ss;
ss << x;
return ss.str();
然后您可以将返回的字符串的字符放入一个 char 数组中,如下所示:
std::string str = to_string(doubleValue);
char digits[str.length()];
然后,感谢 Remy Lebeau 的评论,您可以这样做:
std::strncpy(digits, to_string(doubleValue).c_str(), sizeof(digits))
或者这个:
to_string(doubleValue).copy(digits, sizeof(digits))
【讨论】:
这是等待发生的缓冲区溢出。至少使用std::setprecision()
来控制ostringstream
输出的位数
您的编辑仍有风险。 std::strcpy()
不做任何边界检查。至少使用std::strncpy()
或std::string::copy()
代替,这样您就可以指定char[]
缓冲区的最大大小,例如:std::strncpy(digits, to_string(doubleValue).c_str(), sizeof(digits))
或to_string(doubleValue).copy(digits, sizeof(digits))
@Remy Lebeau 好的,我会更改的,谢谢您指出。【参考方案4】:
如果您想在不使用to_string
的情况下手动转换,您将不得不一次提取一个数字。 double 不会作为一组字符存储在内存中,因此您不能只是复制内存并希望一切正常。 (有关如何解释双打的更多信息,请参阅here)。
【讨论】:
【参考方案5】:先do this:
std::ostringstream strs;
strs << dbl;
std::string str = strs.str();
这会将双精度 dbl
转换为字符串 str
。
然后你可以将它转换成这样的字符数组:
char *cstr = new char[str.length()+1];
str.copy(cstr, str.length());
cstr[str.length()] = '\0';
// use cstr as needed...
delete[] cstr;
或者,简单地说:
const char *cstr = str.c_str();
// use cstr as needed...
【讨论】:
这与使用std::to_string
像问题中提到的OP 有何不同?
@scohe001 to_string 是 C++11。与 stringstream 不同,较旧的编译器将不支持它。【参考方案6】:
在不使用to_string
的情况下,您自己的转换过程可能如下:
char* to_char_array(double num_double, int decimal_place)
int num_int = std::round(num_double * pow(10, decimal_place));
int sign = num_int < 0 ? 1 : 0;
num_int = abs(num_int);
if (num_int == 0)
char* s = (char*)malloc(decimal_place + 3);
s[0] = '0';
s[1] = '.';
for (int i = 2; i < decimal_place + 2; i++)
s[i] = '0';
s[decimal_place + 2] = '\0';
return s;
int digit_count = 1;
int n = num_int;
if (n >= 100000000) digit_count += 8; n /= 100000000;
if (n >= 10000) digit_count += 4; n /= 10000;
if (n >= 100) digit_count += 2; n /= 100;
if (n >= 10) digit_count++;
int size = digit_count + 1 + (decimal_place > 0 ? 1 : 0) + sign;
char* s = (char*)malloc(size);
for (int i = 0, integer = num_int; integer != 0; integer /= 10)
s[size - 2 - i++] = integer % 10 + 48;
if (decimal_place > 0 && i == decimal_place)
s[size - 2 - i++] = '.';
s[size - 1] = '\0';
if (sign)
s[0] = '-';
return s;
void main()
double d = -12.268904;
char* s = to_char_array(d, 3);
cout << "double: " << d << " - char array: " << s << endl;
system("pause");
【讨论】:
【参考方案7】:这样做:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main()
double a=23.25;
char b[12];
stringstream ss;
ss << a;
ss >> b;
cout << b << endl;
return 0;
或者这个:
#include <iostream>
#include <string>
#include <sstream>
#include <stdio.h>
using namespace std;
int main()
double a=23.25;
char b[12];
stringstream ss ;
ss<<a;
sprintf(b,ss.str().c_str());
cout<<b<<endl;
return 0;
或者这个:
here don't forget to
#include<bits/stdc++.h>
double a=23.25;
char b[12];
stringstream ss ;
ss<<a;
strcpy(b,ss.str().c_str());
cout<<b<<endl;
return 0;
【讨论】:
如果您解释为什么每组代码都能解决问题以及每个代码之间的差异(例如性能、易用性等。以上是关于将双精度转换为字符数组 C++的主要内容,如果未能解决你的问题,请参考以下文章