c stdout buffering

c - ¿Por qué printf() no imprime nada antes de dormir()?



stdout buffering (3)

Estoy aprendiendo C con el libro de Kernighan y Ritchie; Estoy en lo básico del cuarto capítulo (cosas de funciones). El otro día comencé a sentir curiosidad por la función sleep() , así que traté de usarla así:

#include <stdio.h> #include <unistd.h> int main(void) { printf(" I like cows."); sleep(5); return 0; }

El problema es la salida del programa, parece que primero se pone en sleep() y luego en printf() , en otras palabras, espera cinco segundos y luego imprime la cadena. Así que pensé, tal vez el programa se queda sleep() tan rápido que no deja que printf() haga su trabajo como yo quiero, es decir, imprime la cadena y luego duerme.

¿Cómo puedo mostrar la cadena y luego poner el programa a dormir? El compilador es GCC 3.3.5 (propolic) en OpenBSD 4.3.

PD. No sé cómo pones aquí las líneas del preprocesador correctamente.


El almacenamiento en búfer significa que toda la salida se almacena en un lugar (denominado memoria intermedia) y se emite después de que haya cierta cantidad de datos en ella. Esto se hace por razones de eficiencia.

Algunas implementaciones (¿la mayoría?) Borran el búfer después de una nueva línea al escribir en la consola, por lo que también puedes probar

printf(" I like cows./n");

en lugar de la llamada a fflush ()


printf() escribe en stdout (la secuencia de salida predeterminada) que generalmente está almacenada en la línea. El búfer no se vacía cuando suena el modo sleep por lo que no se visualiza nada, cuando el programa sale, todas las transmisiones se vacían automáticamente, por lo que se imprime justo antes de salir. La impresión de una nueva línea generalmente hará que la transmisión se vacíe, alternativamente, puede usar la función fflush :

int main(void) { printf(" I like cows./n"); sleep(5); return 0; }

o:

int main(void) { printf(" I like cows."); fflush(stdout); sleep(5); return 0; }

Si está imprimiendo en una transmisión que no está almacenada en línea, como puede ser el caso si se redirige stdout o está escribiendo en un archivo, simplemente imprimir una nueva línea probablemente no funcionará. En tales casos, debe usar fflush si desea que los datos se escriban de inmediato.


Su problema es que printf (y cualquier otra cosa que use la biblioteca stdio para escribir en stdout (salida estándar)) está almacenada en búfer: línea almacenada en búfer si va a la consola y tamaño almacenado en el búfer si va a un archivo. Si haces un fflush(stdout); después del printf , hará lo que quieras. Podría intentar agregar una nueva línea (''/ n'') a su cadena, y eso haría lo correcto, siempre y cuando no redirija la salida estándar a un archivo.

No estoy 100% seguro, pero creo que stderr no está almacenado en el búfer, lo que puede causar confusión porque es posible que vea la salida que realizó en stderr antes de la salida que realizó anteriormente en stdout .