Limpando a "sujeirinha" no buffer do teclado

Publicado por Rogério Bragil em 17/08/2003

[ Hits: 45.249 ]

Blog: http://www.bragil.net

 


Limpando a "sujeirinha" no buffer do teclado



Muitas vezes, quando lemos algum dado com scanf(), sobra alguma "sujeirinha" no buffer do teclado, o que pode levar a erros na execução do código. Por exemplo, compile e execute este código:

#include <stdio.h>

main()
{
     int i;
     char ch;

     for (i=0; i<5; i++)
     {
             printf("Caractere: ");
             scanf("%c", &ch);
     }
     return 0;
}

Ao executar, você verá que não serão lidos todos os caracteres, visto que a função scanf() atribui o "lixo" do buffer para a próxima variável.

Podemos contornar isso de algumas formas. Uma é incluir uma chamada à função getchar() após a leitura com scanf(). Isso garante a limpeza do buffer, evitando erros. Assim:

#include <stdio.h>

main()
{
     int i;
     char ch;

     for (i=0; i<5; i++)
     {
             printf("Caractere: ");
             scanf("%c", &ch);
             getchar();
     }
     return 0; }

Outra forma é fazer com que o próprio scanf() mande o lixo do buffer para o espaço. Assim:

#include <stdio.h>

main()
{
     int i;
     char ch;

     for (i=0; i<5; i++)
     {
             printf("Caractere: ");
             scanf("%c%*c", &ch);   /* perceberam a mudança? */
     }
     return 0;
}

Executem os dois exemplos e você verá que a leitura ocorre sem erros. Agora, basta você escolher qual tática usar.

Outras dicas deste autor

Gerando números aleatórios em C

Buscando intervalo de datas apenas pelo dia e mês no MySQL

Leitura recomendada

Fazendo comparações sem o uso de IF, ELSE em C

Programando no Ubuntu - aplicações gráficas em C++ com Eclipse e Glade

Acessando um valor dada sua posição numa matriz bidimensional

Limpando o buffer do teclado em C

getch() e getche() não funcionam no ANSI

  

Comentários
[1] Comentário enviado por repolho em 18/08/2003 - 12:44h

uma outra coisa eh dar um fflush(stdin) antes de usar o scanf();
;)

Abracos
REPOLHO

[2] Comentário enviado por jllucca em 20/08/2003 - 20:14h

uma coisa que eu apreendi pra fazer ele limpar o buffer antes de pegar uma variavel é dar um espacinho. No caso ficaria scanf(" %c",&ch), eu acho isso bem mais simples e economico. Teria algum motivo para não usar essa maneira?

[3] Comentário enviado por bragil em 21/08/2003 - 00:04h

Pessoal, isso é como neston: existem mil maneiras de preparar, invente uma...

A propósito, fflush() aqui na minha máquina (slack 9, gcc 3.2.2, glibc 2.3.1) não funfa... Coloco antes do scanf(), depois do scanf(), mas não dá certo... A "sujeirinha" ainda fica lá...

Se alguém tiver um relato diferente com relação à fflush(), poste aqui...

bragil

[4] Comentário enviado por Sindolfo em 21/02/2004 - 16:27h

O uso de fflush(stdin) não é portável, funciona no Rwindows mas não no Linux.

[5] Comentário enviado por amcorreia em 17/01/2005 - 14:48h

No linux vc faz:

__fpurge(stdin); (agora nao me lembro se eh um ou dois underline ;)

[6] Comentário enviado por jochan em 14/12/2005 - 14:45h

Muito legal, vai me ajudar bastente no meu projeto de C++ ... =)

[7] Comentário enviado por f_Candido em 09/07/2007 - 16:55h

Bem legal, mas não entendi, o porque do espaço antes, limpar o buffer do teclado. Alguém poderia me dizer???

[8] Comentário enviado por mysosmadeofslack em 18/04/2009 - 18:33h

o que funcionou aqui foi a ultima solução porém invertida

[9] Comentário enviado por ace_aff em 08/09/2009 - 00:50h

O __fpurge(stdin); foi o que resolveu o meu problema por aqui.

To usando o Ubuntu 9.04, mas com kde, kate e gcc


[10] Comentário enviado por gedarius em 30/09/2009 - 15:24h

Pessoal, o uso do fflush() não é recomendado... na propria documentação da função (http://www.utas.edu.au/infosys/info/documentation/C/CStdLib.html#fflush) está escrito: "effect undefined for input streams" o que significa que nunca sabemos a maneira que ela vai se comportar, por isso existem outras maneiras de contornar esse problema, uma delas é a mostrada aqui hehe. claro que isso é a fflush()... mas creio que não seja muito diferente com a __fpurge()!!!

Abraços!

[11] Comentário enviado por spock2f em 19/10/2009 - 04:51h

Só pra contribuir pela ajuda :

__fpurge(stdin);
getchar();

Funcionou comigo encima de uma maquina virutal usando Ubuntu 9.10 + gedit + Gcc..

Obrigado a todos pelas ajudas..

[12] Comentário enviado por stickorz em 19/11/2009 - 22:45h

Olá amigos,
Uma outra forma de evitar os problemas com o buffer do "scanf" é a seguinte:

scanf(" %[^\n]", var); // teclar espaço antes do mod.

Abraços.



Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner
Linux banner
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts