sprintf输出浮点数和双精度变量时的最大字符数量是多少?

7

如果我这样做:

void printfloat(float number)
{
    printf("%f", number);
}

并且

void printdouble(double number)
{
    printf("%f", number);
}

每个函数可以输出的最大字符数是多少?

你总是可以控制那个数量:http://www.lix.polytechnique.fr/~liberti/public/computing/prog/c/C/FUNCTIONS/format.html#width - BlackBear
1
我不想控制它。我想打印出它通常会打印的所有内容,并知道其中的最大值。 - Almo
2
这部分已经有答案了。至少对于双精度浮点数来说:https://dev59.com/TnI-5IYBdhLWcg3wu7Lv - Chase Henslee
太棒了。在发布之前我进行了搜索,但那个并没有出现。在预先搜索中也没有出现。 - Almo
1
@Doug T.:printf不接受指针,它接受的是浮点值本身;%lf格式说明符仅适用于scanf--对于printf没有意义(§7.20.6.1第7段:“长度修饰符及其含义为... l ...对于后面的a、A、e、E、f、F、g或G转换说明符没有影响。”) - Stephen Canon
@Doug T. 在Stephen Canon的评论中补充一点,printf在打印浮点数参数之前会将它们全部转换为双精度。 - Praetorian
3个回答

6

通过使用MS Visual Studio 10进行测试,得出了一个字符串811的结果。

sprintf(buf, "%.*f", 500, -DBL_MAX);

当然,使用更大的精度值可以生成更长的字符串。

但是,如果使用 "%f",输出的最大字符数为 317 + 1(包括 '\0')。
因此,为了编写可移植的代码:

#include <float.h>
#include <stdio.h>

    char buf[1/*'-'*/ + (DBL_MAX_10_EXP+1)/*308+1 digits*/ + 1/*'.'*/ + 6/*Default? precision*/ + 1/*\0*/];
    sprintf(buf, "%f", -DBL_MAX);

函数printfloat(float number)只有一个参数"number",该参数是浮点数,并且范围受限于float类型。它被传递给sprintf()时会被转换成double类型。因此,它的最大值为FLT_MAX。因为最后要加上'\0',所以输出的字符数最多为47 + 1。

    char buf[1/*'-'*/ + (FLT_MAX_10_EXP+1)/*38+1 digits*/ + 1/*'.'*/ + 6/*Default? precision*/ + 1/*\0*/];
    sprintf(buf, "%f", -FLT_MAX);

2

结论:

我无法通过使用snprintf函数来获取字符串的大小,而且我希望代码尽可能地与编译器独立。因此,这里是我想出的解决方案。

char numstr[50];
sprintf_s(numstr, "%g", *value);
m_stringRepresentation += numstr;

%g会以科学计数法输出数字,这严重限制了字符的数量。我选择了一个足够大的缓冲区来容纳任何可能的输出。我的唯一编译器依赖是sprintf_s。


1
一个快速的测试程序通过 wc -c 管道显示 float 有 47 个字符,double 有 317 个字符。该程序如下:
#include <stdio.h>
#include <float.h>

int main(void) {
        printf("%f", -DBL_MAX);
}

请注意,您可以使用snprintf将输出限制为n个字符。

或者使用 snprintf(NULL, 0, ...); 来查找需要多少缓冲区字符,以便您可以分配相应数量的空间。 - Chris Lutz
我可能会在这个评论中使用snprintf解决方案。根据我对该主题的其他阅读,我并不完全相信317是最大值。我大部分是相信的,但还不足以发布关键任务代码。 :) - Almo
我们的代码库中没有定义snprintf。我尝试使用#include "stdio.h",但没有成功。 - Almo
如果您使用的是MSVC,请尝试使用“_snprintf”。 - Praetorian
_snprintf_s告诉我给它的缓冲区太小了。如果我需要知道缓冲区必须有多大才能告诉我需要多大的缓冲区,我就看不出有什么意义了。 - Almo
查看另一个SO讨论(https://dev59.com/gXE85IYBdhLWcg3wKwKD)和其中的链接,很明显微软不关心标准或方便性等琐事。微软表示他们正在专注于C++部分,因此看起来你有几个选择:使用%g,使用大缓冲区(1080?从上面来的),或者使用C++(std::string,我相信)。 - Kevin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接