给定C中的printf语句,如何构造char*缓冲区,并知道它的长度?

don*_*lan 4 c printf mpi output-formatting

我有一个MPI进程,我需要打印到文件.MPI系统使用MPI_File_iwrite等功能命令,它接受缓冲区(例如char指针)和整数长度.然后,缓冲区将打印到文件中.

因此,为了打印我需要打印到文件的内容,我需要以某种方式用一个将格式转换映射到char*缓冲区的函数替换printf函数.这是有问题的,因为字符串的长度可能不同......例如:

printf("something %d, %d, %d, %f, etc.",x,y,z,p,d,...);
Run Code Online (Sandbox Code Playgroud)

如何恢复printf格式化生成的字符串,找出长度是多少,并将其作为char*传递给mpi函数?

mer*_*011 7

看起来你想要使用snprintf足够大的缓冲区.

如果缓冲区足够大,则返回值snprintf等于打印的字符数.您可以将输出字符串的长度计算为缓冲区大小的最小值和返回值snprintf.

  • `snprintf`的整个想法是它可以使用空缓冲区执行"干运行",以预先计算所需的缓冲区长度.因此,如果您拥有"snprintf",请使用它的力量:以两遍方式进行.当然,如果最大缓冲区长度很容易预测,那么可以一次完成.不需要`strlen`,因为所有`... printf`函数都返回它们输出的序列的长度. (3认同)
  • @AnT如果你有堆栈空间,根据我的经验,使用固定大小的本地`char`数组执行第一次`snprintf()`调用会更有效率,该数组足够大,可能在大多数时间工作,并且只有在固定缓冲区太小*然后*动态分配一个足够大的缓冲区并再次调用`snprintf()`.`snprintf()`可能有些昂贵,而`malloc()`可能需要锁定,这会影响性能,特别是对于多线程进程. (2认同)

giu*_*sti 5

您可以使用"打印"0字节到NULL指针snprintf().在这种情况下,不会写入任何字符串,但snprintf()相对于其返回值仍然会正常运行.然后你可以分配一个足够大的缓冲区.

例如:

size_t len;
len = snprintf(NULL, 0, "something %d, %d, %d, %f, etc.",x,y,z,p,d,...);
if (len > 0) {
    char *buf = malloc(len + 1);
    snprintf(buf, len + 1, "something %d, %d, %d, %f, etc.",x,y,z,p,d,...);
}
Run Code Online (Sandbox Code Playgroud)

这仅在C99中有效.

请注意,snprintf()如果存在转换错误,则可以返回负值.只有少数情况会发生这种情况,但它们仍然存在.根据说明符,其输出也可以为零.