如何使用C的sprintf()安全地格式化浮点数/双打?

时间:2010-11-03 21:31:20

标签: c++ c printf

我将我的一个C ++库移植到一个有点不稳定的编译器 - 它不支持字符串流,或者像snprintf()这样的C99功能。我需要将intfloat等格式设置为char*,并且唯一可用的选项似乎是1)使用sprintf() 2)手动滚动格式化过程。< / p>

鉴于此,如何确定(在编译或运行时)格式化浮点值需要多少字节?我的库可能用于模糊测试,因此它需要处理异常或极端值。

或者,是否有一个小的(100-200行首选)可移植的snprintf()实现,我可以将其与我的库捆绑在一起?

理想情况下,我最终会使用基于snprintf()的普通代码或类似内容:

static const size_t FLOAT_BUFFER_SIZE = /* calculate max buffer somehow */;

char *fmt_double(double x)
{
    char *buf = new char[FLOAT_BUFFER_SIZE + 1];
    sprintf(buf, "%f", x);
    return buf;
}

相关问题:

2 个答案:

答案 0 :(得分:3)

编译器是否支持ecvtfcvtgcvt中的任何一个?它们有点怪异,难以使用,但它们有自己的缓冲区(ecvtfcvt)和/或您可能会很幸运,并且发现系统头文件在VC ++中有定义最大字符数gcvt将产生的数量。你可以从那里拿走它。

如果不这样做,我会根据提供的代码考虑以下内容。对于双人来说,500个字符非常保守;有效值大约是10 ^ -308到10 ^ 308,所以即使通过打印出所有数字来确定实现是烦人的,也应该没有溢出。

char *fmt_double(double d) {
    static char buf[500];
    sprintf(buf,"%f",d);
    assert(buf[sizeof buf-1]==0);//if this fails, increase buffer size!
    return strdup(buf);
}

这并没有提供任何惊人的保证,但它应该是非常安全的(tm)。不幸的是,我认为这种方法与这种方法一样好。但如果您习惯于定期运行调试版本,那么至少应该对任何问题进行预警......

答案 1 :(得分:1)

我认为GNU Libiberty就是你想要的。您可以只包含snprintf的实现。

vasprintf.c - 152 LOC。