I am playing with the printf and the idea to write a my_printf(…) that calls the normal printf and a sprintf that sends the result to a special function. (I was thinking about sprintf since that behaves just like printf on most platforms).
My idea was to write a small macro that did this:
#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)
But since sprintf can expand the string to a much bigger size than X, this method breaks almost directly.
And just to add a number do the malloc seems to be the wrong way to attack the problem, since then I would just move the problem into the future and a day when I want print a big expression…
Does anyone has a better idea on how to attack this problem? Or how do I know how big the sprintf result will be?
Thanks Johan
Update: I forgot that printf returns how many chars it prints, and since I already is calling printf in the macro it was a very easy thing to add a int that saves the number.
#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)
Update: I was thinking about this and maybe to use a normal function that looks a lot like what ephemient has suggested is a good idea. The key there seems to be the v-version of the different printf functions (vprintf, vsprintf and vsnprintf). Thanks for pointing that out.
Thanks again Johan
The best way to do this is with varargs. Create a function with the same prototype as printf() and use the varargs functions to pass data to sprintf to populate the desired buffer, the also pass that buffer to printf(‘%s’) before returning.
A lot of the early implementations had a 4K limit on the lowest level printf() call but I would opt for more than that. You probably need to just set an upper limit and stick to it.
One trick we used in a logging system was to write the data using printf() to a /dev/null handle. Since printf() returns the number of characters written, we then used that to allocate a buffer. But that wasn’t very efficient since it involved calling a printf()-type function twice.