Pular para o conteúdo

Limpando a "sujeirinha" no buffer do teclado

Dica publicada em C/C++ / Introdução
Rogério Bragil bragil
Hits: 50.103 Categoria: C/C++ Subcategoria: Introdução
  • Indicar
  • Impressora
  • Denunciar
O Viva o Linux depende da receita de anúncios para se manter. Ative os cookies aqui para nos patrocinar.
Não conseguimos carregar os anúncios. Se usa bloqueador, considere liberar o Viva o Linux para nos patrocinar.

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:

O Viva o Linux depende da receita de anúncios para se manter. Ative os cookies aqui para nos patrocinar.
Não conseguimos carregar os anúncios. Se usa bloqueador, considere liberar o Viva o Linux para nos patrocinar.
#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.

O Viva o Linux depende da receita de anúncios para se manter. Ative os cookies aqui para nos patrocinar.
Não conseguimos carregar os anúncios. Se usa bloqueador, considere liberar o Viva o Linux para nos patrocinar.

Gerando números aleatórios em C

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

Usando o GCC com pthread

Corrigindo o erro: C compiler cannot create executables

Getchar(); sendo ignorado? Não mais!

Série de Fibonacci usando recursividade em linguagem C

Sites recomendados para estudar linguagem C

#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

Entre na sua conta para comentar.