如何防止将double转换为char时出现缓冲区溢出?

如何防止将double转换为char时出现缓冲区溢出?,c,arrays,string,C,Arrays,String,我正在将double转换为char字符串: char txt[10]; double num; num = 45.344322345 sprintf(txt, "%.1f", num); 并使用“.1f”将小数点截断为十分之一位。 i、 e.-txt包含45.3 我通常在sprintf中使用precision来确保char缓冲区不会溢出。 在这里,我如何在不使用snprintf的情况下截断十进制数呢 (即,由于某种原因,如果num=345694876345.3) 谢谢 编辑如果num是>缓

我正在将double转换为char字符串:

char txt[10];
double num;

num = 45.344322345

sprintf(txt, "%.1f", num);
并使用“.1f”将小数点截断为十分之一位。
i、 e.-txt包含45.3

我通常在sprintf中使用precision来确保char缓冲区不会溢出。 在这里,我如何在不使用snprintf的情况下截断十进制数呢

(即,由于某种原因,如果num=345694876345.3)

谢谢

编辑如果num是>缓冲区,则结果不再重要,只是不想崩溃。不知道在这种情况下什么才是最有意义的

EDIT2我应该比在标签中更清楚地说明这是一个C程序。
我在C程序中使用snprintf时遇到问题

为什么不使用
snprintf
?您应该使用
snprintf
,而不管格式字符串是否包含双精度、另一个字符串或任何其他内容。就我所知,没有理由不这样做。

你为什么要在没有
snprintf
的情况下这样做?您应该使用
snprintf
,而不管格式字符串是否包含双精度、另一个字符串或任何其他内容。据我所知,没有理由不使用。

使用
snprintf()
,它将告诉您有多少字节未打印。通常,数组的大小应该足够大,以处理目标整数类型的最长字符串表示形式。如果事先不知道,请使用
malloc()
(或
asprintf()
,这是非标准的,但在许多平台上都有)

编辑

snprintf()
将正常失败,如果格式超过给定的缓冲区,则不会溢出。如果你不需要处理这个问题,那么简单地使用它就能解决你的问题。我想不出有哪一个实例您不想处理这个问题,但话说回来,我不会处理您正在处理的任何问题:)

使用
snprintf()
,它会告诉您有多少字节未打印。通常,数组的大小应该足够大,以处理目标整数类型的最长字符串表示形式。如果事先不知道,请使用
malloc()
(或
asprintf()
,这是非标准的,但在许多平台上都有)

编辑


snprintf()
将正常失败,如果格式超过给定的缓冲区,则不会溢出。如果你不需要处理这个问题,那么简单地使用它就能解决你的问题。我想不出有哪种情况下你不想处理它,但话说回来,我不是在处理你正在处理的任何事情:)

如果你绝对必须自己做,请在尝试转换之前数一数数字中的数字:

int whole = num;
int wholeDigits = 0;
do {
    ++wholeDigits;
}
while (whole /= 10);

double fraction = num - (int) num;
int decimallDigits = 0;
while (fraction > 0) {
    ++decimalDigits;
    fraction *= 10;
    fraction = fraction - (int) fraction;
}

int totalLength = decimalDigits ? wholeDigits + decimalDigits + 1 : wholeDigits;

在依赖它来防止崩溃之前,您可能应该验证此特殊代码是否按照公布的方式工作。我建议您使用
snprintf
或类似的代码,而不是像其他人所说的那样使用我的代码。

如果您必须自己完成,请在尝试转换之前先计算数字中的位数:

int whole = num;
int wholeDigits = 0;
do {
    ++wholeDigits;
}
while (whole /= 10);

double fraction = num - (int) num;
int decimallDigits = 0;
while (fraction > 0) {
    ++decimalDigits;
    fraction *= 10;
    fraction = fraction - (int) fraction;
}

int totalLength = decimalDigits ? wholeDigits + decimalDigits + 1 : wholeDigits;

在依赖它来防止崩溃之前,您可能应该验证此特殊代码是否按照公布的方式工作。我建议您使用
snprintf
或类似的东西,而不是像其他人所说的那样使用我的代码。

为什么不把缓冲区设置得足够大,以容纳double的最大字符串表示形式呢

假设64位双精度浮点运算使用IEEE标准,尾数使用52位:2^52=4503599627370500。所以我们需要16个字符来保存小数点前后的所有数字。19考虑小数点、符号字符和空终止符

我只需要使用至少20个字符的缓冲区大小,然后继续


如果需要使用科学记数法打印双精度,则需要为指数添加足够的空间。假设一个11位有符号指数,则指数的另4个字符加上指数的符号和字母“E”。在这种情况下,我只需要30个字符。

为什么不把缓冲区设置得足够大,以容纳double的最大字符串表示形式呢

假设64位双精度浮点运算使用IEEE标准,尾数使用52位:2^52=4503599627370500。所以我们需要16个字符来保存小数点前后的所有数字。19考虑小数点、符号字符和空终止符

我只需要使用至少20个字符的缓冲区大小,然后继续


如果需要使用科学记数法打印双精度,则需要为指数添加足够的空间。假设一个11位有符号指数,则指数的另4个字符加上指数的符号和字母“E”。在这种情况下,我只需要30个字符。

如果它不能正确打印结果,您希望结果是什么?如果它不能正确打印结果,您希望结果是什么?我只需要将其设置为40,然后继续。除非它是一个数组,否则这40个字节比你的时间要便宜得多。但我也喜欢snprintf。我会把它改成40,然后继续前进。除非它是一个数组,否则这40个字节比你的时间要便宜得多。但我也喜欢snprintf。