将未知长度的格式化数据写入字符串(C编程)

Cha*_*les 10 c string printf

以下C函数:

int sprintf ( char * str, const char * format, ... );
Run Code Online (Sandbox Code Playgroud)

将格式化数据写入字符串.作为str传递的数组的大小应该足以包含整个格式化的字符串.但是,如果格式化字符串的长度未提前知道怎么办?如何使用此函数(或类似其他函数)写入格式化数据,其长度未知?

例如:

#include <stdio.h>

int main ()
{
  char buffer [13];
  int n, a=5, b=3;
  n=sprintf (buffer, "%d plus %d is %d", a, b, a+b);
  printf ("[%s] is a %d char long string\n",buffer,n);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

缓冲区需要为13或更大才能使其正常工作.如果字符串长度未知,并且缓冲区(例如)已设置为5,则此操作无效.我需要能够为碰巧大于缓冲区的字符串动态分配或重新分配缓冲区的东西.

Dig*_*oss 17

使用snprintf

大多数人会告诉你使用snprintf()它,因为它不会超出缓冲区的末尾.

这是好建议.通常的"设计模式"是声明一个临时固定大小的缓冲区,该缓冲区大于字符串可能的大小snprintf().如果字符串需要保存一段时间,则可以测量其长度,malloc(3)另一个,以及strcpy(3)临时缓冲区到半永久malloc()缓冲区.


两遍方法

还有另一种方式.

C99指定如果缓冲区为NULL,则不写入任何字节,但返回将写入的实际长度.这允许你做一个虚拟的第一次传递,malloc()一个缓冲区,然后snprintf()到那个缓冲区.(理论上你可以使用普通的sprintf(),因为长度现在已知,但我不会.)

无论如何,如果我的程序必须在过去的每个操作系统上运行,我不确定我会依赖所有这些,但对于大多数人来说这是一个合理的模式.


JSB*_*ոգչ 8

你想要的是这两个功能之一:*snprintf(http://libslack.org/manpages/snprintf.3.html).它将输出缓冲区的长度作为其第二个参数,如果缓冲区对于结果来说太小,它将返回所需的字符数,允许您重新分配更大的缓冲区.*asprintf.它需要一个char **参数并分配足够的内存来保存输出,只要有足够多的连续虚拟内存可用.free如果在程序退出之前已完成它,则必须调用将其从内存中删除,并且可能需要内存以用于其他内容.