Flush stdout Output Stream in C
-
Usa la funzione
fflush
per scaricare lo stream di outputstdout
in C -
Dimostrare il comportamento di
fflush
usando la funzioneprintf
in C
Questo articolo mostrerà diversi metodi su come svuotare il flusso di output stdout
in C.
Usa la funzione fflush
per scaricare lo stream di output stdout
in C
La libreria standard C fornisce una libreria I/O
, stdio
, che essenzialmente rappresenta una versione bufferizzata delle operazioni di I/O eseguite nello spazio utente, migliorando così le prestazioni per i casi d’uso comuni. In generale, l’accesso ai file e l’esecuzione di operazioni su di essi è fornito dai servizi del sistema operativo; quindi, l’utente alla fine necessita di una chiamata di sistema, ad es. per aprire un file. Una frequente invocazione di chiamate di sistema rende il programma più lento poiché implica l’accesso alle strutture dati del kernel del sistema operativo e il trasferimento del controllo avanti e indietro. Di conseguenza, ci sono buffer mantenuti dalla libreria C per gestire le operazioni di input/output quando si usano le chiamate alla funzione stdio
.
Se l’utente deve forzare la scrittura nei buffer del kernel, deve svuotare il flusso fornito dalla funzione fflush
. fflush
accetta un singolo argomento del puntatore FILE
al flusso specificato. Si noti che fflush
forza la funzione di scrittura per i flussi di output mentre elimina i dati memorizzati nel buffer per i flussi di input (con file ricercabili). Se l’argomento è NULL
, scarica tutti i flussi di output aperti.
Attenzione però, fflush
non garantisce che i dati scritti siano fisicamente archiviati in quanto ciò richiede lo svuotamento dei buffer del kernel (cosa che può essere eseguita usando la chiamata fsync
vista qui).
#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);
}
Produzione:
Username: tmp
Your username is set to - tmp
Dimostrare il comportamento di fflush
usando la funzione printf
in C
Nota che alcuni flussi (ad esempio stderr
) non sono bufferizzati. Al contrario, la funzione printf
che scrive implicitamente nel flusso stdout
è bufferizzata, e se eseguiamo il bucle infinito stampando un singolo carattere ogni iterazione sotto il cofano, non invierà il contenuto al flusso finché il buffer interno non sarà pieno. Pertanto, il seguente esempio di codice produce la stampa a raffica dei caratteri del punto lista. Si noti che chiamiamo la funzione usleep
ogni iterazione per rallentare l’esecuzione dell’occhio umano in modo che sia chiaramente osservabile.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
while (1) {
printf(".");
usleep(1e3);
}
exit(EXIT_SUCCESS);
}
In alternativa, se sostituiamo la chiamata printf
con fprintf
, che stampa nel flusso stderr
, produrrà il comportamento di stampa iterativo char per char ogni secondo. Anche in questo caso, il ritardo di 1 secondo a ogni iterazione viene utilizzato solo per garantire una buona dimostrazione.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
while (1) {
fprintf(stderr, ".");
sleep(1);
}
exit(EXIT_SUCCESS);
}
Infine, se avessimo bisogno di imitare lo stesso comportamento sul flusso stdout
come visto nel codice di esempio precedente, possiamo aggiungere la chiamata fflush
dopo la funzione printf
. Ciò costringerà i buffer della libreria C a essere scritti nei buffer del kernel ad ogni iterazione, risultando in un comportamento simile.
#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