这可以自定义printf吗?

Cor*_*ren 11 c linux customization glibc

我有一些需要经常打印的结构.现在,我正在使用这个结构的经典打印包装器:

void printf_mystruct(struct* my_struct)
{
   if (my_struct==NULL) return;
   printf("[value1:%d value2:%d]", struct->value1, struct->value2);
}
Run Code Online (Sandbox Code Playgroud)

这个功能很方便,但也非常有限.我不能在不制作新包装的情况下预先添加或附加一些文本.我知道我可以使用va_arg系列来预装或推出一些文本,但我觉得我会重新实现这个轮子.

我想知道是否可以为printf编写自定义功能.我希望能够写出这样的东西:

register2printf("%mys", &printf_mystruct); 
...
if (incorrect)
  printf("[%l] Struct is incorrect : %mys\n", log_level, my_struct);
Run Code Online (Sandbox Code Playgroud)

这可能吗 ?我怎样才能做到这一点 ?

注意:我在Ubuntu Linux 10.04下使用gcc.

Bas*_*tch 12

对不起,但是在带有Glibc的Linux上,一些答案是不正确的

在Linux上使用GNU的glibc,你可以自定义的printf:你会打电话 register_printf_function来,例如定义的含义%Y在printf格式字符串.

但是,这种行为是Glibc特有的,甚至可能已经过时......我不确定我会推荐这种方法!

如果用C++编码,C++流库中有你可以扩展的操纵器,你也可以为你的类型重载operator << 等.

在2018年2月添加

您可以考虑编写一个GCC插件来帮助它(并改进某些扩展的类型检查printf).这可能并不容易(可能是几周或几个月的工作),而且它将是GCC版本特定的(GCC 7和GCC 8的插件代码不一样).你可以添加一些特定的信息#pragma来通知你的插件有关你的额外控制字符串说明符%Y和它们所期望的类型.你的插件应该改变format属性的处理(也许在gcc/tree.c)

  • 正如您所预测的,“register_printf_function()”已被弃用。但是,添加了一个更新的函数:“register_printf_specifier()”。它的用法与旧的非常相似。我编写了一个示例来注册“%b”说明符,用于以二进制形式打印无符号整数类型,您可以在 CodeReview 上看到:[c - 注册“%b”转换说明符](https://codereview.stackexchange.com/q /219994/200418)。 (4认同)
  • 不,你不需要编译Glibc.您只需要使用Glibc(即C或C++中的任何Linux程序)从程序中调用`register_printf_function`.但是,这不适用于非Glibc系统(例如MacOSX或FreeBSD).它实际上主要在Linux上运行. (3认同)

Dav*_*nan 5

这在标准 C 中是不可能的。您不能扩展printf以添加自定义格式字符串。您的辅助函数方法可能与您在 C 的约束范围内获得的一样好。