Flush Stdout Output Stream em C
-
Use a função
fflush
para liberar fluxo de saídastdout
em C -
Demonstre o comportamento
fflush
usando a funçãoprintf
em C
Este artigo demonstrará vários métodos sobre como liberar o fluxo de saída stdout
em C.
Use a função fflush
para liberar fluxo de saída stdout
em C
A biblioteca padrão C fornece uma biblioteca I/O
, stdio
, que essencialmente representa uma versão em buffer de operações I/O feitas no espaço do usuário, melhorando assim o desempenho para casos de uso comuns. Geralmente, o acesso a arquivos e a condução de operações sobre eles é fornecido pelos serviços do sistema operacional; assim, o usuário eventualmente precisa de uma chamada de sistema, por exemplo, para abrir um arquivo. Uma invocação frequente de chamadas de sistema torna o programa mais lento, pois acarreta o acesso às estruturas de dados do kernel do sistema operacional e a transferência de controle para frente e para trás. Como resultado, existem buffers mantidos pela biblioteca C para lidar com as operações de entrada/saída ao usar as chamadas de função stdio
.
Se o usuário precisa forçar a gravação nos buffers do kernel, ele precisa liberar o fluxo fornecido pela função fflush
. fflush
recebe um único argumento do ponteiro FILE
para o fluxo fornecido. Observe que fflush
força a função de gravação para fluxos de saída enquanto descarta quaisquer dados em buffer para fluxos de entrada (com arquivos pesquisáveis). Se o argumento for NULL
, ele esvazia todos os fluxos de saída abertos.
Porém, lembre-se de que fflush
não garante que os dados gravados sejam armazenados fisicamente, pois isso requer que os buffers do kernel sejam liberados (o que pode ser feito usando a chamada fsync
vista aqui).
#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);
}
Resultado:
Username: tmp
Your username is set to - tmp
Demonstre o comportamento fflush
usando a função printf
em C
Observe que alguns fluxos (por exemplo, stderr
) não são armazenados em buffer. Em contraste, a função printf
que escreve implicitamente para o fluxo stdout
é armazenada em buffer, e se executarmos o loop infinito imprimindo um único caractere a cada iteração embaixo do capô, ele não enviará o conteúdo para o fluxo até que o buffer interno seja completo. Portanto, o exemplo de código a seguir resulta na impressão intermitente dos caracteres de marcador. Observe que chamamos a função usleep
a cada iteração para desacelerar a execução do olho humano para que seja claramente observável.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
while (1) {
printf(".");
usleep(1e3);
}
exit(EXIT_SUCCESS);
}
Alternativamente, se substituirmos a chamada printf
por fprintf
, que imprime no fluxo stderr
, ele produzirá o comportamento iterativo de impressão char por char a cada segundo. Novamente, o atraso de 1 segundo a cada iteração é colocado apenas para garantir uma boa demonstração.
#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, se precisarmos imitar o mesmo comportamento no fluxo stdout
como visto no código do exemplo anterior, podemos adicionar a chamada fflush
após a função printf
. Isso forçará os buffers da biblioteca C a serem gravados nos buffers do kernel a cada iteração, resultando em um comportamento semelhante.
#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