Is this possible to customize printf?
I have some struct that I need to print frequently. For now, I am using a classical print wrapper around this struct :
void printf_mystruct(struct* my_struct)
{
if (my_struct==NULL) return;
printf("[value1:%d value2:%d]", struct->value1, struct->value2);
}
This function is handy, but is also really limited. I cannot prepen or append some text without making a new wrapper. I know that I can use va_arg family to be able to prepend or apprend some text, but I feel like I would be re-implementing the wheel.
I am wondering if it's possible to write a customizing function to printf. I would like to be able to write something like this :
register2printf("%mys", &printf_mystruct);
...
if (incorrect)
printf("[%l] Struct is incorrect : %mys\n", log_level, my_struct);
Is this possible ? How can I do this ?
NB: I am under Ubuntu Linux 10.04 and I use gcc.
Sorry, but some answers are incorrect on Linux with Glibc
On Linux with a GNU Glibc, you can customize printf: you would call
register_printf_function
to e.g. define the meaning of %Y
in your printf
format strings.
However, this behavior is Glibc specific, and might even become obsolete... I'm not sure I would recommend this approach!
If coding in C++, the C++ stream library has manipulators which you could extend, and you can also overload for your types the operator <<
etc.
added in february 2018
You could consider writing a GCC plugin helping that (and improving the typechecking of some extended printf
). It won't be easy (probably a few weeks or months of work), and it would be GCC version specific (not the same plugin code for GCC 7 and GCC 8). you might add some specific #pragma
to inform your plugin about extra control string specifiers like your %Y
and the type expected for them. Your plugin should change the handling of format
attribute (perhaps in gcc/tree.c
)
This is not possible in standard C. You cannot extend printf
to add custom format strings. Your helper function approach is probably about as good as you will get within the constraints of C.
No, this is not possible. An alternative is to make your own wrapper around printf()
itself. It would parse the format string and process conversions like printf()
does. If a conversion is one of your custom conversions, it would print whatever you need, and if not, it would call one of the system's *printf()
functions to have it perform the conversion for you.
Note that this is a non-trivial task, and you have to be careful to parse the format string exactly like printf()
does. See man 3 printf
. You can read the variable argument list using functions in <stdarg.h>
.
Once you have such a wrapper, you can make it extensible by employing function pointers (the custom conversions don't have to be hard-coded into the wrapper).
You can use the sprintf
function to obtain a string representation of your struct:
char* repr_mystruct(char* buffer, struct* my_struct)
{
sprintf(buffer, "[string:%s value1:%d value2:%d]", struct->value1, struct->value2);
return buffer;
}
and subsequently print the data to your output stream
char buffer[512]; //However large you need it to be
printf("My struct is: %s", repr_mystruct(buffer, &my_struct))
Edit: Modified the function to allow the passing of a buffer (see discussion below).
Note 2: The format string requires three arguments but in the example only two are passed.