如何计算sprintf将产生的输出长度?

alk*_*ows 16 c printf

目标:将数据序列化为JSON.

问题:我事先不知道整数是多少个字符.

我认为这样做的一个好方法是使用 sprintf()

size_t length = sprintf(no_buff, "{data:%d}",12312);
char *buff = malloc(length);
snprintf(buff, length, "{data:%d}",12312);
//buff is passed on ...
Run Code Online (Sandbox Code Playgroud)

当然我可以使用堆栈变量char a[256]代替no_buff.

问题:但是在C中是否存在像unix这样的一次性写入的实用程序/dev/null?像这样的Smth:

#define FORGET_ABOUT_THIS ...
size_t length = sprintf(FORGET_ABOUT_THIS, "{data:%d}",12312);
Run Code Online (Sandbox Code Playgroud)

ps我知道我也可以通过日志获得整数的长度,但这种方式似乎更好.

mya*_*aut 22

由于C是简单语言的地方,因此没有"一次性缓冲区"这样的东西 - 所有内存管理都在程序员的肩膀上(这些都有GNU C编译器扩展,但它们不是标准的).

不能事先知道整数是多少个字符.

为您的问题提供了更简单的解决方案.snprintf知道!

在兼容C99的平台上,使用NULL作为第一个参数调用snprintf:

ssize_t bufsz = snprintf(NULL, 0, "{data:%d}",12312);
char* buf = malloc(bufsz + 1);
snprintf(buf, bufsz + 1, "{data:%d}",12312);

...

free(buf);
Run Code Online (Sandbox Code Playgroud)

在较旧的Visual Studio版本(具有非C99兼容的CRT)中,请使用_scprintf而不是snprintf(NULL, ...)调用.

  • 注意:snprintf()也可能返回-1,并且在转角情况下会遇到麻烦,因为size_t和int的最大值很少相同。如果2`snprintf()`在它们之间的`locale`改变和第二`输出更长,则可能有问题。 (3认同)

Bri*_*ell 14

您可以打电话int len = snprintf(NULL, 0, "{data:%d}", 12312)来测试您需要多少空间.

snprintf将打印最多size字符,size第二个参数在哪里,并返回打印整个事物所需的字符数,不计算终止'\0'.因为你传入0,它实际上不会写任何东西(因此将避免通过尝试取消引用会发生任何空指针异常NULL),但它仍将返回适合整个输出所需的长度,你可以用来分配你的缓冲区.

此时,您可以分配并打印到缓冲区,记住还要包含一个用于尾随的缓冲区'\0':

char *buf = malloc(len + 1);
snprintf(buf, len + 1, "{data:%d}", 12312);
Run Code Online (Sandbox Code Playgroud)


M.M*_*M.M 5

要获得您可以写的长度:

int length = snprintf(NULL, 0, "{data:%d}", 12312);
Run Code Online (Sandbox Code Playgroud)

请注意,返回类型是int.-1如果出现某种错误,它可能会返回.确保您的输入数据不包含可能导致总长度超过的长字符串INT_MAX!