Flujo de salida estándar en C
-
Utilice la función
fflush
para descargar el flujo de salidastdout
en C -
Demuestre el comportamiento
fflush
utilizando la funciónprintf
en C
Este artículo demostrará varios métodos sobre cómo vaciar el flujo de salida stdout
en C.
Utilice la función fflush
para descargar el flujo de salida stdout
en C
La biblioteca estándar de C proporciona una biblioteca de E/S
, stdio
, que esencialmente representa una versión almacenada en búfer de las operaciones de E/S realizadas en el espacio de usuario, mejorando así el rendimiento para casos de uso comunes. Generalmente, el acceso a archivos y la realización de operaciones en ellos es proporcionado por los servicios del sistema operativo; por tanto, el usuario eventualmente necesita una llamada al sistema, para abrir un archivo. Una invocación frecuente de llamadas al sistema hace que el programa sea más lento, ya que implica acceder a las estructuras de datos del núcleo del sistema operativo y transferir el control de un lado a otro. Como resultado, hay búferes mantenidos por la biblioteca C para manejar las operaciones de entrada/salida cuando se usan las llamadas a la función stdio
.
Si el usuario necesita forzar la escritura en los búferes del kernel, necesita vaciar el flujo proporcionado por la función fflush
. fflush
toma un único argumento del puntero FILE
al flujo dado. Tenga en cuenta que fflush
fuerza la función de escritura para los flujos de salida mientras descarta los datos almacenados en búfer para los flujos de entrada (con archivos buscables). Si el argumento es NULL
, elimina todos los flujos de salida abiertos.
Sin embargo, tenga en cuenta que fflush
no garantiza que los datos escritos se almacenen físicamente, ya que eso requiere que los búferes del kernel se descarguen (lo que se puede lograr usando la llamada fsync
que se ve aquí).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
char *username;
size_t len;
int lnmax = 256;
username = malloc(lnmax);
if (username == NULL) perror("malloc");
printf("Username: ");
fflush(stdout);
if (fgets(username, lnmax, stdin) == NULL) exit(EXIT_FAILURE);
printf("Your username is set to - %s", username);
exit(EXIT_SUCCESS);
}
Producción :
Username: tmp
Your username is set to - tmp
Demuestre el comportamiento fflush
utilizando la función printf
en C
Tenga en cuenta que algunas transmisiones (por ejemplo, stderr
) no se almacenan en búfer. Por el contrario, la función printf
que escribe implícitamente en el flujo stdout
está almacenada en búfer, y si ejecutamos el bucle infinito imprimiendo un solo carácter en cada iteración debajo del capó, no enviará el contenido al flujo hasta que el búfer interno sea lleno. Por lo tanto, el siguiente ejemplo de código da como resultado la impresión en ráfaga de los caracteres de viñeta. Observe que llamamos a la función usleep
cada iteración para ralentizar la ejecución del ojo humano para que sea claramente observable.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
while (1) {
printf(".");
usleep(1e3);
}
exit(EXIT_SUCCESS);
}
Alternativamente, si sustituimos la llamada printf
con fprintf
, que imprime en el flujo stderr
, producirá el comportamiento de impresión iterativo char por char cada segundo. Una vez más, el retraso de 1 segundo en cada iteración se coloca solo para garantizar una buena demostración.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
while (1) {
fprintf(stderr, ".");
sleep(1);
}
exit(EXIT_SUCCESS);
}
Finalmente, si necesitáramos imitar el mismo comportamiento en la secuencia stdout
como se ve en el código de ejemplo anterior, podemos agregar la llamada fflush
después de la función printf
. Esto obligará a que los búferes de la biblioteca C se escriban en búferes del kernel en cada iteración, lo que dará como resultado un comportamiento similar.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
while (1) {
printf(".");
fflush(stdout);
sleep(1);
}
exit(EXIT_SUCCESS);
}
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook