2008-12-03 60 views
15

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 me entró la curiosidad acerca de la función sleep(), por lo que trató de utilizar de esta manera:¿Por qué printf() no imprime nada antes de dormir()?

#include <stdio.h> 
#include <unistd.h> 

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

El problema es la salida del programa, se ve como lo hace el sleep() primero y luego el printf(), en otra palabras, espera cinco segundos y luego imprime la cadena. Así que pensé, tal vez el programa llega al sleep() tan rápido que no deja que printf() haga su trabajo como yo quiero, es decir, imprimir la cadena y luego dormir.

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

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

Respuesta

2

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 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 se almacena temporalmente, lo que puede causar confusión, ya que podría ver una salida que hizo al stderr antes de la salida se hizo anteriormente para stdout.

+0

printf no es amortiguada , la secuencia a la que está escribiendo es. –

+0

stderr suele estar sin búfer (aunque puede ser una línea amortiguada). –

31

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 se llama al sleep, por lo que no se muestra nada, cuando el programa sale, todas las transmisiones se vacían automáticamente, por lo que se imprime justo antes de salir. Impresión de una nueva línea por lo general hacer que el flujo sea lavado, otra posibilidad es utilizar 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 a una corriente que no esté búfer de línea, como puede ser el caso si se redirige stdout o si 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 inmediatamente.

+0

Tiene un \ n adicional en el segundo ejemplo –

+0

El motivo por el que se agrega \ n a la cadena funciona es que printf a la consola está almacenado en la línea.Sin embargo, si lo redirige a un archivo, puede que no sea suficiente porque utiliza un esquema de almacenamiento en búfer diferente. –

+0

Interesante pregunta entonces es, ¿cómo se puede saber qué modo de almacenamiento en búfer utiliza su puntero de archivo actual? –

3

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 una cierta cantidad de datos en ella. Esto se hace por razones de eficiencia.

Algunos (la mayoría?) Implementaciones vaciar el búfer después de un salto de línea al escribir en la consola, por lo que también puede intentar

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

en lugar de la llamada a fflush()

Cuestiones relacionadas