一个更好的sprintf?

时间:2014-03-29 01:32:20

标签: c linux

我对C很新。最近我一直致力于通过套接字,MQSeries和其他途径从一堆其他系统获取输入的系统。基本上我的工作是将这些不同的源集合在一起,并将它们放入一种类似于本地的XML格式,并将它们存储在适当的数据库中,或者将它们传递给其他系统。因此,我正在创建格式化的字符串 all 。非常简化,他们看起来像这样:

"<tag>lotsa string data</tag>...repeat ad ad nauseam"

所以我开始使用sprintfvsprintf并且很容易编写一个例程来连接sprintf的格式字符串,但问题是我没有关于sprintf长度的高级知识我收到的字符串,因此很难知道要分配的缓冲区的大小。我得到的字符串可以是25个字节长或250k字节。不说。所以我当然要过一次或两次缓冲。这导致我使用snprintf这是正常的,但只是在它被截断后重新尝试缓冲区并再次尝试重新启动缓冲区。

所以我知道这不是宇宙中最大的问题,我可以自己加总长度,但有没有办法让它在C中更容易一些,或者我应该停止抱怨并弄清楚某种递归函数提前添加所有字符串长度?

3 个答案:

答案 0 :(得分:4)

就像许多事情一样,有人在你发牢骚之前然后划伤了痒。 asprintf and vasprintf救援。它们并没有比sprintf做得更多,但它们完全困扰你的是什么,即弄清楚需要多少空间然后分配它,格式化字符串,然后传回来给你。

有几点需要注意:

  • 如果出现问题,他们将返回-1,如果没有,则返回字符串的长度

  • 需要记住在完成后释放字符串。

  • 它们不属于C或POSIX,因此您的平台可能没有它们。

  • 由于您使用的是Linux,因此可以使用它们,但您需要定义_GNU_SOURCE功能宏

一个半荒谬的例子:

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>

void doSomething(char *str)
{
    printf("%s\n", str);
}

int main(int argc, char *argv[])
{
    char *opentag = "bold";
    char *str1 = "first string ";
    char *str2 = "second string ";
    char *str3 = "third string ";
    char *closetag = "/bold";
    char *output_string;

    asprintf(&output_string, "<%s>%s%s%s<%s>", opentag, str1, str2, str3, closetag);

    doSomething(output_string);

    free(output_string);

    return(0);
}

答案 1 :(得分:0)

我和你说错了,但是如果你使用了堆栈怎么办?因为编译器会分配和释放使用的内存,而不必担心是否会溢出缓冲区。

答案 2 :(得分:0)

此外(也就是说)使用asprintf(例如answered by Duck),您可以考虑使用glib功能,例如g_strdup_printf