Quiero usar printf para alguna depuración básica (Sí, estoy familiarizado con gdb, etc.). Como printf almacena en memoria intermedia, se requiere una llamada a fflush (stdout) inmediatamente después de printf. Pensé en escribir un simple envoltorio. Entonces el contenedor será algo como esto:

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

Creo que la implementación de dicha función sería algo como esto:

   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);

   }

Sé que hay funciones / macros como va_list, va_start y va_args, pero eso requerirá que analice la cadena de formato printf para obtener el tipo y quiero evitar hacerlo. ¿Hay un enfoque simple? Como esto es solo para fines de depuración, no me importa tener el tipo de formato restringido a% d,% f y% s.

0
asinix 15 jun. 2020 a las 17:15

3 respuestas

La mejor respuesta

Simplemente use setvbuf y configure la secuencia para que esté en línea.

setvbuf(stdout, NULL, _IOLBL, 0);

¿Hay un enfoque simple?

Claro, solo reenvíe los argumentos.

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
}

Todas las funciones estándar *printf tienen alternativas v*printf que aceptan un argumento va_list. Si no los conocía aquí hay una buena referencia sobre cppreference.

Aquí hay funciones / macros como va_list, va_start y va_args, pero eso requerirá que analice la cadena de formato printf para obtener el tipo

Eso está mal: el uso de macros va_* no requiere que analice la cadena de formato printf.

3
KamilCuk 15 jun. 2020 a las 17:32

Use stderr y fprintf. Stderr no tiene búfer por defecto.

Esta pregunta se responde con más detalle aquí:

¿Por qué printf no se vacía después de la llamada a menos que haya una nueva línea en la cadena de formato?

1
bstache 15 jun. 2020 a las 14:21

Como una extensión (y tal vez alguna corrección) a la respuesta @KamilCuk.

Si usa el compilador de la familia gcc, puede usar el atributo de función especial que muestra al compilador que la función es similar a printf. El compilador analizará la cadena de formato y emitirá las advertencias, igual que cuando se usa 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

1
P__J__ 15 jun. 2020 a las 15:25