¿La línea stdout está en búfer, no en búfer o indeterminada por defecto?
c99 buffered (1)
La sección 7.9.13/7
de c99
establece que:
Al inicio del programa, tres flujos de texto están predefinidos y no es necesario que se abran explícitamente: entrada estándar (para leer entrada convencional), salida estándar (para escribir salida convencional) y error estándar (para escribir salida de diagnóstico).
Como se abrió inicialmente, el flujo de error estándar no está completamente almacenado en búfer; la entrada estándar y las secuencias de salida estándar están completamente almacenadas en búfer si, y solo si se puede determinar que la secuencia no se refiere a un dispositivo interactivo.
Así que eso tiene sentido. Si está empujando su salida estándar a un archivo, quiere que esté completamente almacenado para la eficiencia.
Pero no puedo encontrar ninguna mención en el estándar en cuanto a si la salida tiene búfer de línea o no está en búfer cuando no se puede determinar que el dispositivo no sea interactivo (es decir, la salida normal a un terminal).
La razón por la que pregunto fue un comentario a mi respuesta here que debería insertar un fflush(stdout);
entre las dos afirmaciones:
printf ("Enter number> ");
// fflush (stdout); needed ?
if (fgets (buff, sizeof(buff), stdin) == NULL) { ... }
porque no estaba terminando el printf
con una nueva linea. ¿Alguien puede aclarar esto?
El estándar C99 no especifica si los tres flujos estándar están sin almacenamiento o con búfer de línea: depende de la implementación. Todas las implementaciones de UNIX que conozco tienen un stdin
búfer de línea. En Linux, stdout
en línea con búfer y stderr
sin búfer.
Que yo sepa, POSIX no impone restricciones adicionales. La página fflush de POSIX no se nota en la sección EJEMPLOS:
[...] La función fflush () se usa porque la salida estándar suele estar en búfer y es posible que la solicitud no se imprima inmediatamente en la salida o el terminal.
Así que la observación de que agrega 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 R. señala, solo puede hacer esto una vez, y debe ser antes de escribir en la salida estándar o realizar cualquier otra operación en él. (C99 7.19.5.5 2)
Acabo de leer un hilo reciente en comp.lang.c
sobre la misma cosa. Una de las observaciones:
La convención de Unix es que
stdin
ystdout
tienenstdout
línea cuando están asociados con un terminal, y de otro modo están completamente en búfer (también conocido como bloque de búfer).stderr
siempre está sin búfer.