Arquivos de Tags: scanf

Limpando o buffer em C

Começando logo com um exemplo prático, compile o código abaixo e execute-o.

#include <stdio.h>

int main()

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

Resultado:

Print screen do monstrando a execução de um programa com o buffer sujo em C

Da para notar que ao digitar o primeiro caractere ‘a’ no nosso caso, ele armazena ‘a’ na variável  e quando e pedido pela segunda vez ele pula para a terceira, ou seja passa direto pelo segundo scanf(), por que isso acontece? Isso acontece pois o buffer contém uma “sujeirinha” visto que a função scanf() atribui o “lixo” do buffer para a próxima variável.

O que fazer para evitar esse problema?

Existem diversas soluções.

  1. A mais simples( é também a que costumo utilizar), adicionar um espaço, desse jeito scanf(” %s”, &var), viram o espaço em branco antes do ‘%’, somente isso já basta para resolver os problemas com o buffer cheio, sem precisar apelar para fgets.
  2. Utilizar a função getchar() também resolve :)
  3. Outra opção é fazer o scanf(); mandar o lixo para o espaço: scanf(“%c%*c”, &ch);  dessa forma.
  4. Simplesmente scanf(” %c”, &ch); notem que existe um espaço entre a aspa de abertura e o %c, isso já resolve o problema.
  5. Mais uma alternativa e usar a função __fpurge(stdin); lembrando para utilizar essa função precisa incluir a lib #include<stdio_ext.h>, se utilizar ela não precisa chamar stdio.h, essa lib só funciona no Linux.

Opções são bastante resta só escolher a que mais gosta e evitar o uso de fflush(stdin).

Por que não usar fflush(stdin)?

Na documentação da função fflush() está escrito: “effect undefined for input streams” (efeitos indefinidos para fluxos de entrada ). Acontece que a função scanf() e uma função de entrada de dados não de saída, se os criadores da função não sabem os possíveis efeitos do uso de fflush em streams de entrada, então acaba não se tornando uma boa pratica de programação é em sistemas unix-like ela não vai limpar o buffer

Referências:

http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1052863818&id=1043284351

http://forum.imasters.uol.com.br/index.php?/topic/336835-tutorial-systempause-e-fflushstdin/

http://www.utas.edu.au/infosys/info/documentation/C/CStdLib.html#fflush

http://www.vivaolinux.com.br/dica/Limpando-a-sujeirinha-no-buffer-do-teclado

[]‘s

Problemas com scanf+strings? Aqui a solução

Algumas pessoas tem problema com o uso de scanf, principalmente no uso de espaços nas strings, para resolver isso tem um macete muito simples. Digamos o código abaixo:

#include<stdio.h>
int main()
{
char frase[50];
printf("Digite a uma frase: ");
scanf("%s",frase);
printf("A frase digitada foi: %s\n");
return 0;
}

Compile: gcc frase.c -o frase

Resultado:

bash-3.1$ frase
Digite a uma frase: joao caiu feio
A frase digitada foi: joao
bash-3.1$

Para resolve esse problema do scanf não capturando o resto da frase usando o parâmetro %[^\n] ao invés de %s, por exemplo:

#include<stdio.h>
int main()
{
char frase[50];
printf("Digite a uma frase: ");
scanf("%[^\n]",frase);
printf("A frase digitada foi: %s\n");
return 0;
}

Compile: gcc frase2.c -o frase2

Resultado:

bash-3.1$ ex6
Digite a uma frase: joao caiu feio
A frase digitada foi: joao caiu feio
bash-3.1$

Agora a frase foi devidamente capturando, para evitarmos overflows no uso desse parâmetro no scanf, colocando %limite[^\n], sendo limite igual ao valor máximo de caracteres que a função scanf ira armazenar na variável. Ficando desta forma.

#include<stdio.h>
int main()
{
char frase[50];
printf("Digite a uma frase: ");
scanf("%49[^\n]",frase);
printf("A frase digitada foi: %s\n");
return 0;
}

Para limpar o buffer após o uso de scanf com este parâmetro, usamos getchar() após o scanf.

#include<stdio.h>
int main()
{
char frase[50];
printf("Digite a uma frase: ");
scanf("%49[^\n]",frase);
getchar();
printf("A frase digitada foi: %s\n");
return 0;
}

Espero que a dica sirva para poderem resolver seus problemas o uso de scanf e strings. Bons estudos a todos. Nas referências tem um link com um tabela informando uma serie de parâmetros interessantes para o uso de scanf, no segundo link tem uma artigo do com diversas dicas para printf e scanf a dupla dinâmica.

Referência:

Como usar o scanf() para strings com espaços
Parâmetros interessantes do scanf e do printf em C

Pagina 1 of 11
SEO Powered by Platinum SEO from Techblissonline