2011-11-09 16 views
6
#include<stdio.h> 
#include <unistd.h> 
int main(){ 
     while(1) 
     { 

       fprintf(stdout,"hello-out"); 
       fprintf(stderr,"hello-err"); 
       sleep(1); 
     } 
     return 0; 
} 

Al compilar este programa en gcc y al ejecutarlo solo se imprime hello-err y no hello-out. ¿Por qué es así? ¿Puede alguien explicar el motivo?¿por qué este programa c no imprime la primera instrucción printf?

+0

¿Cuál es su plataforma? –

+0

¿Dónde miraba su texto impreso? Primero 'printf' está imprimiendo a' stdout' y luego a 'stderr'.En su caso, podría ser para diferentes flujos de salida – Nekto

+0

@ JimBuck-Estoy trabajando en Fedora Linux. – bornfree

Respuesta

17

Si agrega un '\n' a su mensaje, lo hará (o debería), es decir. "hello-out\n".

La razón es que es stdout tamponada con el fin de ser más eficiente, mientras que stderr no almacena su salida y es más apropiado para los mensajes de error y las cosas que necesitan ser impresos inmediatamente.

stdout se generalmente ser enrojecida cuando:

  • Una nueva línea (\n) se va a imprimir
  • usted lee desde stdin
  • fflush() es invocado

EDITAR: La otra cosa que quería agregar antes de que mi computadora fallara ... dos veces ... fue que también puede usar setbuf(stdout, NULL); para deshabilitar el almacenamiento en memoria intermedia de stdout. Lo he hecho antes cuando tuve que usar write() (Unix) y no quería que mi salida se almacenara en el búfer.

+0

+1 para setbuf (stdout, NULL) –

+1

¡Gracias por tu explicación! – bornfree

+0

@bornfree: sin preocupaciones, espero haberlo explicado bien. – AusCBloke

1

Olvidó las nuevas líneas (notó \n) en sus cadenas. O si necesita llamar fflush(NULL); o al menos antes de fflush(stdout);sleep(1);

Y fprintf(stdout, ...) es la misma que printf(...)

Es necesario que las nuevas líneas de salida o para llamar fflush debido a que (al menos en Linux) el búfer de stdout ARCHIVO es línea- amortiguado. Esto significa que la biblioteca C está almacenando datos en el búfer, y realmente lo generará (usando el write Linux system call) cuando el búfer esté lo suficientemente lleno, o cuando lo vacíe con una nueva línea, o llamando al fflush. El almacenamiento en búfer es necesario porque las llamadas al sistema son costosas (llamar a write por cada byte que se envía es realmente demasiado lento). Lea también la página del manual de setbuf

+1

¿Puede explicar por qué es necesario? Quiero entender la razón detrás de esto. – bornfree

+0

La respuesta de AusCBloke lo explica. –

+0

como otros han respondido, porque está almacenado en búfer para reducir las operaciones de E/S. llamar a fflush() obligaría a enjuagar el búfer. – LeleDumbo

3

No siempre de impresión a cabo la salida a la salida estándar, porque por la salida estándar de diseño se almacena temporalmente la salida, y stderres sin búfer. En general, para un flujo de salida con búfer, el flujo no se descarga hasta que el sistema sea "libre" para hacerlo. Entonces, los datos pueden continuar almacenándose en búfer por un tiempo largo, antes de que se vacíe. Si desea forzar el buffer para lavar puede hacerlo a mano utilizando fflush

#include<stdio.h> 
#include <unistd.h> 
int main(){ 
     while(1) 
     { 

       fprintf(stdout,"hello-out"); 
       fflush(stdout); /* force flush */ 
       fprintf(stderr,"hello-err"); 
       sleep(1); 
     } 
     return 0; 
} 

Actualización: stdout se linebuffered cuando está conectado a un terminal, y simplemente tamponada de otro modo (por ejemplo, una redirección o un tubo)

+0

¡Gracias! Entendí el punto. – bornfree

Cuestiones relacionadas