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

时间:2010-05-12 00:10:38

标签: c arrays string

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

char txt[10];
double num;

num = 45.344322345

sprintf(txt, "%.1f", num);

并使用“.1f”截断小数位,到十分位数 即-txt包含45.3

我通常在sprintf中使用precision来确保char缓冲区不会溢出。 我怎么能在这里也截断小数,而不使用snprintf?

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

由于

编辑如果num是>缓冲结果不再重要,只是不想崩溃。不确定那种情况下最有意义的是什么。

EDIT2 我应该比标签更清晰,这是一个C程序。 我在C程序中使用snprintf时遇到问题。 I don't want to add any 3rd party libraries.

4 个答案:

答案 0 :(得分:5)

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

修改

如果格式超出给定缓冲区,

snprintf()将正常失败,它不会溢出。如果您不需要处理,那么只需使用它就可以解决您的问题。我想不出你不会想要来处理它的实例,但话又说回来,我不会处理你正在做的任何事情:)

答案 1 :(得分:3)

为什么不让你的缓冲区足够大以容纳双倍的最大可能字符串表示?

假设使用IEEE标准进行浮点运算的64位双精度,其使用52位作为尾数:2 ^ 52 = 4,503,599,627,370,500。所以我们需要16个字符来保存小数点前后的所有数字。 19考虑小数点,符号字符和空终止符。

我只会使用至少20个字符的缓冲区大小并继续前进。

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

答案 2 :(得分:2)

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

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;

您应该验证此ad-hoc代码是否像宣传的那样工作,然后再依赖它来防止崩溃。我建议您使用snprintf或类似的东西代替我的代码,正如其他人所说的那样。

答案 3 :(得分:1)

为什么不在没有snprintf的情况下执行此操作?无论您的格式字符串是否包含double,另一个字符串或其他任何内容,您都应该使用snprintf。据我所知,没有理由