0

I want to use printf for some basic debugging (Yes, I am familiar with gdb, etc.). As printf buffers, a call to fflush(stdout) is required immediately after a printf. I thought of writing a simple wrapper. So the wrapper will be something like this:

   flushedPrintf(int noArgs, args to be passed to printf);

I think that the implementation of such a function would be something like this:

   void flushedPrintf(int noArgs, args to be passed to printf) {

       char *myString = malloc(MAX_LENGTH_DEFINED);
       sprintf(myString, ....args to be passed to printf);

       printf("%s", myString);
       fflush(stdout);

   }

I know there are functions/macros like va_list, va_start and va_args but those will require me to parse the printf format string to get the type and I want to avoid doing that. Is there a simple approach? As this is only for debugging purpose, I do not mind having the format type restricted to %d, %f and %s.

asinix
  • 766
  • 6
  • 15

3 Answers3

3

Just use setvbuf and set the stream to be line buffered.

setvbuf(stdout, NULL, _IOLBL, 0);

Is there a simple approach?

Sure, just forward the arguments.

void flushedPrintf(const char *fmt, ...) {
   va_list va;
   va_start(va, fmt);
   vprintf(fmt, va);
   va_end(va);
   fflush(stdout);
   // TODO: propagate return value from vprintf and fflush
}

All standard *printf functions have v*printf alternatives that accept a va_list argument. If you didn't know about them here is a nice reference on cppreference.

here are functions/macros like va_list, va_start and va_args but those will require me to parse the printf format string to get the type

That's wrong - using va_* macros do not require you to parse printf format string.

KamilCuk
  • 69,546
  • 5
  • 27
  • 60
1

Use stderr and fprintf. Stderr is unbuffered by default.

This question is answered in better detail here:

Why does printf not flush after the call unless a newline is in the format string?

bstache
  • 11
  • 2
1

As an extension (and maybe some correction) to the @KamilCuk answer.

If you use gcc family compiler you can use the special function attribute showing the compiler that the function is printf-like. The compiler will analyse the format string and emit the warnings - same as when using printf.

int flushedPrintf(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
int flushedPrintf(const char *fmt, ...) 
{
   int result;
   va_list va;
   va_start(va, fmt);
   result = vprintf(fmt, va);
   va_end(va);
   fflush(stdout);
   return result;
}

https://godbolt.org/z/SbGRxk

0___________
  • 34,740
  • 4
  • 19
  • 48