当前位置:  开发笔记 > 运维 > 正文

创建一个my_printf,将数据发送到sprintf和普通printf?

如何解决《创建一个my_printf,将数据发送到sprintf和普通printf?》经验,为你挑选了3个好方法。

我正在使用printf和想法来编写调用普通printf的my_printf(...)和将结果发送到特殊函数的sprintf.(我在考虑sprintf,因为在大多数平台上它的行为与printf一样).

我的想法是编写一个执行此操作的小宏:

#define my_printf(X, Y...) do{ printf(X, ## Y); \
    char* data = malloc(strlen(X)*sizeof(char)); \
    sprintf(data, X, ## Y); \
    other_print(data);\
    free(data);}while(0)

但是由于sprintf可以将字符串扩展到比X大得多的大小,因此这种方法几乎可以直接打破.

只是为了添加一个数字,malloc似乎是解决问题的错误方法,因为那时我只是将问题转移到未来,有一天我想要打印一个大表达......

有没有人对如何解决这个问题有更好的想法?或者我怎么知道sprintf结果会有多大?

谢谢约翰


更新:我忘记了printf返回它打印的字符数,因为我已经在宏中调用了printf,所以添加一个保存数字的int是一件非常容易的事情.

#define buf_printf(X, Y...) do{ int len = printf(X, ## Y); \
    char* data = malloc((len+1)*sizeof(char)); \
    sprintf(data, X, ## Y); \
    other_print(data);\
    free(data);}while(0)

更新:我正在考虑这个问题,并且可能使用一个看起来很像ephemient所建议的正常函数是一个好主意.关键似乎是不同printf函数的v版本(vprintf,vsprintf和vsnprintf).感谢您指出了这一点.

再次感谢约翰



1> Steve Jessop..:

使用snprintf计算大小.从手册页:

"如果由于此限制而导致输出被截断,那么返回值是字符数(不包括尾随'\ 0'),如果有足够的空间可用,它将被写入最终字符串"

snprintf是C99的标准配置.如果您只有C89编译器,请检查文档:预标准版本可能不会返回您想要的值.再次根据手册页,如果输出被截断,则版本2.1之前的glibc用于返回-1,而不是所需的大小.

顺便说一下,sizeof(char)被定义为1,总是在每个C实现中:-)



2> paxdiablo..:

最好的方法是使用varargs.使用与printf()相同的原型创建一个函数,并使用varargs函数将数据传递给sprintf以填充所需的缓冲区,并在返回之前将该缓冲区传递给printf("%s").

许多早期的实现对最低级别的printf()调用有4K限制,但我会选择更多.您可能需要设置一个上限并坚持下去.

我们在日志记录系统中使用的一个技巧是使用printf()将数据写入/ dev/null句柄.由于printf()返回写入的字符数,因此我们使用它来分配缓冲区.但这不是很有效,因为它涉及调用printf() - 类型函数两次.



3> qrdl..:

因为你在Linux上我建议使用asprintf()- 它为你分配字符串的GNU扩展.感谢C99可变参数宏,你不需要混淆varagrs.

所以你的宏看起来像:

#define MY_PRINT(...) do { \
                          char *data; \
                          asprintf(&data, __VA_ARGS__); \
                          printf("%s", data); \
                          other_print(data); \
                          free(data); \
                      } while (0)

NB!这是C99和GNU专用代码

编辑:现在它将只评估一次宏参数,因此使用类似("%d",i ++)的方式调用宏将正常工作.

推荐阅读
低调pasta_730
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有