¿Está la línea estándar almacenada en búfer, sin búfer o indeterminada de forma predeterminada?

La sección 7.9.13/7 de c99 establece que:

Al iniciar el progtwig, tres flujos de texto están predefinidos y no necesitan abrirse explícitamente: entrada estándar (para leer la entrada convencional), salida estándar (para escribir salida convencional) y error estándar (para escribir la salida de diagnóstico).

Como se abrió inicialmente, el flujo de error estándar no está completamente almacenado en el búfer; la entrada estándar y las secuencias de salida estándar están completamente almacenadas en el búfer si y solo si se puede determinar que la transmisión no se refiere a un dispositivo interactivo.

Entonces eso tiene sentido. Si está empujando su salida estándar a un archivo, quiere que esté completamente almacenado para mayor eficiencia.

Pero no puedo encontrar ninguna mención en el estándar en cuanto a si la salida está en línea con búfer o sin búfer cuando no se puede determinar que el dispositivo no sea interactivo (es decir, salida normal a un terminal).

La razón por la que pregunto fue un comentario a mi respuesta aquí que debería insertar un fflush(stdout); entre las dos declaraciones:

 printf ("Enter number> "); // fflush (stdout); needed ? if (fgets (buff, sizeof(buff), stdin) == NULL) { ... } 

porque no estaba terminando el printf con una nueva línea. ¿Alguien puede aclarar esto?

El estándar C99 no especifica si las tres transmisiones estándar están sin búfer o búfer de línea: depende de la implementación. Todas las implementaciones de UNIX que conozco tienen un stdin buffer de línea. En Linux, stdout en línea con búfer y stderr sin búfer.

Hasta donde yo sé, POSIX no impone restricciones adicionales. La página fflush de POSIX nota en la sección EJEMPLOS:

[…] La función fflush () se utiliza porque la salida estándar suele estar almacenada en el búfer y es posible que el aviso no se imprima inmediatamente en la salida o el terminal.

Entonces la observación de que agregas fflush(stdout); es correcto.


Una alternativa podría ser hacer stdout sin búfer:

 setbuf(stdout, NULL); /* or */ setvbuf(stdout, NULL, _IONBF, 0); 

Pero como señala R., solo puede hacer esto una vez, y debe ser antes de escribir en stdout o realizar cualquier otra operación sobre él. (C99 7.19.5.5 2)


Acabo de leer un hilo reciente en comp.lang.c sobre lo mismo. Uno de los comentarios:

La convención de Unix es que stdin y stdout son buffer de línea cuando se asocian con un terminal, y de otro modo son completamente búfidos (también conocidos como buffer-buffer). stderr siempre está sin búfer.

Intereting Posts