Buffer é uma área de armazenamento temporário. Todos os dispositivos padrão de entrada e saída contêm um buffer de entrada e saída. No C, os streams (fluxos de dados) são armazenados em um buffer, por exemplo, no caso da entrada padrão, quando pressionamos uma tecla no teclado, seu código é armazenado no buffer pelo sistema operacional para posteriormente ser lido pelo programa.
Em algumas ocasiões, pode ser necessário limpar um conteúdo indesejado do buffer para obter uma próxima entrada desejada e não um valor residual da entrada anterior. Por exemplo, ao se utilizar um scanf ( ) , o <enter > digitado permanecerá no buffer, fazendo com que ele possa "pular" um próximo scanf ( ) que aguarde um caractere ou uma string..
Uma opção bastante utilizada é a função fflush (), que deveria normalmente ser usada apenas para fluxo de saída. Sua finalidade é limpar (ou liberar) o buffer de saída e mover os dados do buffer para o console (no caso de stdout) ou disco (no caso de fluxo de saída em arquivo). Sua sintaxe é
int fflush (FILE * ostream);
onde ostream aponta para um fluxo de saída ou um fluxo de atualização em que a operação mais recente não foi inserida. A função fflush faz com que todos os dados não gravados para esse fluxo sejam entregues ao SO para serem gravados no arquivo.
De acordo com o padrão C, usar fflush (stdin) para limpar o buffer de teclado pode apresentar um comportamento indefinido. No entanto, alguns compiladores permitem isso. Veja o exemplo
#include <stdio.h>
int main()
{
char c1, c2;
printf("Digite um caractere: ");
scanf("%c",&c1);// Entra um caractere + o <enter>
fflush(stdin); /* Retira o <enter> do buffer para
permitir a entrada do próximo
caractere */
printf("Digite outro caractere: ");
scanf("%c",&c1);
printf("C1 = %c e C2 =%c", c1, c2);
}
Não se trata de uma questão de "quão ruim" isso é. fflush (stdin) simplesmente não é portável (assim como o __fpurge(stdin) do Linux), então não deve ser usado se o desejo é gerar um código portável entre compiladores.
Na sequência apresentaremos algumas alternativas ao uso de fflush(stdin):
Alternativa 1:
#include <stdio.h>
int main()
{
char c1, c2;
printf("Digite um caractere: ");;
scanf("%c",&c1); /* Entra um caractere mais o
<enter> */
printf("Digite outro caractere: ");
scanf(" %c",&c2); /* o espaço faz o programa C
desconsiderar o <enter> */
printf("C1 = %c e C2 =%c", c1, c2);
}
Alternativa 2:
#include <stdio.h>
int main()
{
char c1, c2;
printf("Digite um caractere: ");;
scanf("%c%*c",&c1); /* Vão ser lidos 1 caractere e
o '\n', o %*c faz o <enter>
ser descartado */
printf("Digite outro caractere: ");
scanf("%c",&c2);
printf("C1 = %c e C2 =%c", c1, c2);
}
Alternativa 3 (pode ser usada com getchar):
include <stdio.h>
#define LIMPABUFFER while(getchar()!='\n')
/* lê todos os caracteres do buffer e os descarta
(incluindo o '\n'), ou seja, esvazia o buffer de
entrada */
int main()
{
char c1, c2;
printf("Digite um caractere: ");
scanf("%c%, &c1);
LIMPABUFFER;
printf("Digite outro caractere: ");
scanf("%c", &c2); // ou c2 = getchar()
printf("C1 = %c e C2 =%c", c1, c2);
}