Pra entender melhor, faça o teste usando as 3 funções uma após outra. Ao fazer isso, ao tentar ler o caractere na segunda função o programa vai simplesmente colocar o enter (\n) e já pula pra terceira.
A limpeza de buffer serve pra evitar este tipo de problema. Logo após a leitura, usa o fflush (no windows) ou __fpurge (no linux) que resolve isso.
obs.: se for usuário linux, o fpurge é antecedido por 2 underline e não apenas 1.
Oii.. Estou fazendo um programa muito simples para descobrir o numero que o computador "pensou" usando a função rand().. mas ele sempre "pensa" no numero 41.. neste caso o fflush() nao deu certo.. Como limpo o buffet neste caso??
7 de junho de 2014 às 15:48
Anônimo disse...
e o comando setbuff(stdin,NULL); mais recomendado ?
No capítulo passado não se pediu pra usar a função scanf() e sim a função getc(stdin) então não tem como dar o espaço: scanf(" %c",&letra2);
Com a função getc(stdin) eu achei outra solução:
int main(void) { char letra1, letra2;
printf("Insira um caractere: "); letra1 = getc(stdin); getchar(); //Esse getchar() sem atribuição lê o [Enter](que seria o \n) que antes era atribuido ao letra2 printf("Insira outro caractere: "); letra2 = getc(stdin); printf("Voce digitou: %c%c", letra1, letra2);
return 0; }
20 de agosto de 2014 às 11:50
Anônimo disse...
Nas minhas aulas meu professor disse para usar esse fflush(stdin), mas eu nunca entendi o porquê! E agora, lendo essa explicação, tudo ficou claro e agora até saber explicar eu sei. Obrigado :)
Olá Gostaria mais que se ensinasse a forma correta de proceder com esses comandos e não o atalho, mesmo simples. Pois a boca entorta com o uso do cachimbo. obrigado.
26 de setembro de 2014 às 14:26
Anônimo disse...
Qual é a forma mais adequada de resolver o problema do buffer?
Quando digito o primeiro nome e a temperatura, quando aperto enter ele já pula para segunda temperatura. Eu coloquei o getchar(); depois da primeira temperatura e funcionou, mas não sei se é a coisa correta a fazer neste caso.
15 de abril de 2015 às 07:20
Anônimo disse...
Comigo nenhum desses funcionou no Linux, então usei o comando setbuf(stdin, NULL); e resolvi. Acho que ele também funciona para Windows, pois setbuf parece ser um acrônimo para set buffer, ou seja, configurar o Buffer.
5 de julho de 2015 às 15:16
Anônimo disse...
Anônimo que perguntou qual a maneira mais adequada de resolver o problema do Buffer, não existe. Simples assim. Você escolhe como vai fazer.
Caramba, eu não estava conseguindo limpar o buffer. Pensei que era _fpurge(stdin), com só uma underline, mas percebi agora que são duas __, demorei um pouco pra entender, só dava erro. haha Valeu.
14 de fevereiro de 2016 às 12:03
Rayane Santos disse...
Excelente! Obrigada...
Quase sempre não comento, mas dessa vez ajudou bastante mesmo!
No Linux, ao tentar compilar o programa, dá o seguinte erro:
winter@winter-desktop:~/C$ cc problemas_getc.c problemas_getc.c: In function ‘main’: problemas_getc.c:12:2: warning: implicit declaration of function ‘__fpurge’ [-Wimplicit-function-declaration] __fpurge(stdin);
Para solucionar o problema, basta adicionar no cabeçalho do arquivo:
Olá. Estou com um "pequeno problema" se assim posso dizer programo c no linux, e obviamente utilizando o compilador gcc, toda vez que compilo o código onde utilizo o __fpurge dá um aviso de declaração implícita da função, porem funciona, só que me incomoda esse aviso, poderiam me dizer o porque? Ou não tem nenhum problema.
Não é recomendado o uso de fflush(stdin), ele é usado para trabalhar com stdout. Mais aconselhável para limpar buffer de entrar, na maioria dos caso e não todos, é o setbuf(stdin, NULL)
Segundo o pessoal da softblue uma forma de limpar o buffer é criar um ponteiro de char no inicio do programa e cada vez que quizer limpar o buffer é só dar um scanf passando %c &c: Exemplo: int main() { char *c;
char letra1, letra2;
printf("Insira um caractere: "); scanf("%c", &letra1); // limpeza do buffer scanf("%c",&c);
printf("Insira outro caractere: "); // limpeza do buffer scanf("%c", &letra2);
printf("Você digitou: '%c' e '%c'", letra1, letra2); // é so colar "scanf("%c",&c);" para cada limpeza
scanf("%c",&c); return 0; }
scanf("%c",&c); return 0; } Isso faz o terminal "segurar a tela" para leitura no final tb para quem usa visual express como eu. Caso tenha alguem interessado em aprender c podemos criar um grupo de whats e aprender c juntos.
Tamy Caroline, sobre a função rand(), sei q a resposta está meio atrasada, mas o caso da função rand() sempre pensar, ao executar inicialmente um programa, o mesmo valor, se dá por causa da semente que se continua o mesmo. No caso, para o computador mudar a semente, é recomendado que vc utilize o tempo como semente: #include "stdio.h" #include "time.h" #include "stdlib.h" int main (){ srand(time(NULL)); //mudando a semente para o tempo do computador //depois vc segue com a função rand normalmente e cada nova execução, ele gerará valores diferentes [...] }
4 de junho de 2018 às 13:09
Anônimo disse...
O que o Fabio disse acima está correto. o comando fflush(stdin) não é recomendado para limpar o stdin. Sugiro o uso do modo como ele fez p limpar o stdin e também deixo duas funções que são ótimas para limpar o stdin:
main (void) { setlocale(LC_ALL,"portuguese"); system ("color 3E");
char letra1, letra2;
printf("Insira um caractere: "); letra1 = fgetc(stind);
fflush(stdin);
printf("Insira outro caractere: "); letra2 = fgetc(stind);
printf("Você digitou: '%c' e '%c'", letra1, letra2);
}
Só não funcionou com o "fgetc(stind);"
Não entendi porque isso aconteceu. Fiquei a me perguntar se essa função pertence ao linux. utilizo o windows.
12 de setembro de 2018 às 13:13
Ana disse...
jean carlos conceição experimente "fgetc(stdin);" stind deve ser uma gralha.
27 de janeiro de 2019 às 12:00
Anônimo disse...
Parabéns pelo criador desse curso. É muito bom mesmo, ensina coisas que nem na faculdade eu vi.
26 de março de 2020 às 10:11
No artigo passado foi pedido o seguinte programa:
Fazer um programa em C que peça dois caracteres ao usuário e os exiba.
Porém, há um problema ao se fazer isso, que e o que vai ser explicado nesse artigo de nossa apostila de C.
Apostila de C - Download
O problema de usar scanf, getchar, getc e fgetc para receber caracteres em C
Pronto! Agora funciona perfeitamente!
Pois esse simples espaço é um comando para o C desconsiderar o enter, tab ou espaço em branco.
Sim, precisa nem dar enter. Tente aí digitar uma letra, dar espaço (ou tab) e a outra.
Ok, mas só é possível fazer isso na scanf().
E na getchar(), getc() e fgetc()?
Limpando o buffer em C: fflush e __fpurge
Ainda no primeiro exemplo desse artigo ( o que dá problema ), digitamos a letra 'C', que é armazenada na variável 'letra1' e em seguida apertamos enter.
Esse caractere (enter), ficará armazenado no buffer do teclado (um memória temporária).
Em seguida, noss programa em C pede para que algo seja armazenado na variável 'letra2'.
Porém, antes do C receber um novo dado do usuário, ele checa se não tem mais alguma coisa armazenada no teclado (ele sempre faz isso...fez antes, para pegar a letra 'C'). E lá tem um caractere sim, o enter.
Então o programa pega esse caractere e o coloca na variável letra2, e é por isso que aparece uma quebra de linha em nosso programa.
Portanto, uma alternativa, caso não queria usar o espaço entre " e o %c na scanf, é limpar o buffer após cada scanf(), getchar(), getc() ou fgetc().
Para limpar o buffer em Windows, use: fflush(stdin)
Para limpar o buffer em Linux, use: __fpurge(stdin)
Veja como fica nosso programa original, funcionando do jeito que queríamos:
#include <stdio.h>
int main()
{
char letra1, letra2;
printf("Insira um caractere: ");
scanf("%c", &letra1);
fflush(stdin);
__fpurge(stdin);
printf("Insira outro caractere: ");
scanf("%c", &letra2);
printf("Você digitou: '%c' e '%c'", letra1, letra2);
}
Fica ao seu dispor escolher como vai ser.
E se habitue com essas coisas, em C há várias maneiras de se fazer várias coisas. Muitas vezes, porém, a solução que usamos não é muito segura ou portável, mas é a mais simples.
Limpar o buffer, por exemplo, nem sempre é algo desejável, e para programação mais profissional e segura não é recomendado que se use fflush por exemplo.
Mas para quem está começando, não há problema algum ficar limpando o buffer após cada scanf, e o scanf (embora seja arriscado e não indicado em alguns casos) é o mais usado.
Por isso, usaremos bastante o scanf ao longo de nosso curso de C.
postado por Programação Progressiva às 10:18 em 9 de dez. de 2012
28 Comentários
Fechar esta janela Ir para formulário de comentárioUsar
getchar();
getchar();
}
no final dos programas, faz limpeza de buffer?
26 de maio de 2014 às 14:04
Não Vinicius, você entendeu errado!
Pra entender melhor, faça o teste usando as 3 funções uma após outra. Ao fazer isso, ao tentar ler o caractere na segunda função o programa vai simplesmente colocar o enter (\n) e já pula pra terceira.
A limpeza de buffer serve pra evitar este tipo de problema.
Logo após a leitura, usa o fflush (no windows) ou __fpurge (no linux) que resolve isso.
obs.: se for usuário linux, o fpurge é antecedido por 2 underline e não apenas 1.
T+
2 de junho de 2014 às 07:47
Oii.. Estou fazendo um programa muito simples para descobrir o numero que o computador "pensou" usando a função rand().. mas ele sempre "pensa" no numero 41.. neste caso o fflush() nao deu certo.. Como limpo o buffet neste caso??
7 de junho de 2014 às 15:48
e o comando setbuff(stdin,NULL);
mais recomendado ?
23 de junho de 2014 às 19:03
Olá!! Também pode resolver o problema simplesmente adicionando um espaço antes do %c. O código ficaria assim:
#include <stdio.h>
int main()
{
char letra1, letra2;
printf("Insira um caractere: ");
scanf(" %c",&letra1);
printf("Insira outro caractere: ");
scanf(" %c",&letra2);
printf("Você digitou: '%c' e '%c'", letra1, letra2);
}
Abraços.
20 de julho de 2014 às 17:32
No capítulo passado não se pediu pra usar a função scanf() e sim a função getc(stdin) então não tem como dar o espaço:
scanf(" %c",&letra2);
Com a função getc(stdin) eu achei outra solução:
int main(void)
{
char
letra1,
letra2;
printf("Insira um caractere: ");
letra1 = getc(stdin);
getchar(); //Esse getchar() sem atribuição lê o [Enter](que seria o \n) que antes era atribuido ao letra2
printf("Insira outro caractere: ");
letra2 = getc(stdin);
printf("Voce digitou: %c%c", letra1, letra2);
return 0;
}
20 de agosto de 2014 às 11:50
Nas minhas aulas meu professor disse para usar esse fflush(stdin), mas eu nunca entendi o porquê! E agora, lendo essa explicação, tudo ficou claro e agora até saber explicar eu sei. Obrigado :)
23 de agosto de 2014 às 05:18
Olá
Gostaria mais que se ensinasse a forma correta de proceder com esses comandos e não o atalho, mesmo simples. Pois a boca entorta com o uso do cachimbo.
obrigado.
26 de setembro de 2014 às 14:26
Qual é a forma mais adequada de resolver o problema do buffer?
22 de março de 2015 às 11:16
#include
int main()
{char letra1, letra2;
printf("Insira um caractere: " );
scanf("%c%c",&letra1,&letra2);
printf("Você digitou: '%c' e '%c' ", letra1, letra2);}
1 de abril de 2015 às 10:12
Esse é melhor!
#include
int main()
{char letra1, letra2;
printf("Insira um/dois caractere:");
scanf("%c %c",&letra1,&letra2);
printf("Você digitou:'%c' e '%c'", letra1, letra2);}
1 de abril de 2015 às 10:34
Olá...
Estou tendo dificuldade parecida com a primeira situação neste post.
#include
int main(){
char A[15], B[15], C[15], D[15], E[15];
int A1, B1, C1, D1, E1;
printf("\n\nDigite o nome do primeiro município:\n* ");
scanf("%15[^\n]", A);
printf("Temperatura média:\n* ");
scanf("%d", &A1);
printf("\n\nDigite o nome do segundo município:\n* ");
scanf("%15[^\n]", B);
printf("\nTemperatura média:\n* ");
scanf("%d", &B1);
Quando digito o primeiro nome e a temperatura, quando aperto enter ele já pula para segunda temperatura.
Eu coloquei o getchar(); depois da primeira temperatura e funcionou, mas não sei se é a coisa correta a fazer neste caso.
15 de abril de 2015 às 07:20
Comigo nenhum desses funcionou no Linux, então usei o comando setbuf(stdin, NULL); e resolvi. Acho que ele também funciona para Windows, pois setbuf parece ser um acrônimo para set buffer, ou seja, configurar o Buffer.
5 de julho de 2015 às 15:16
Anônimo que perguntou qual a maneira mais adequada de resolver o problema do Buffer, não existe. Simples assim. Você escolhe como vai fazer.
14 de julho de 2015 às 09:20
Deu certo para o que eu precisava.
Obrigado
22 de novembro de 2015 às 18:18
Caramba, eu não estava conseguindo limpar o buffer.
Pensei que era _fpurge(stdin), com só uma underline, mas percebi agora que são duas __, demorei um pouco pra entender, só dava erro. haha
Valeu.
14 de fevereiro de 2016 às 12:03
Excelente! Obrigada...
Quase sempre não comento, mas dessa vez ajudou bastante mesmo!
Vlw
4 de junho de 2016 às 07:47
No Linux, ao tentar compilar o programa, dá o seguinte erro:
winter@winter-desktop:~/C$ cc problemas_getc.c
problemas_getc.c: In function ‘main’:
problemas_getc.c:12:2: warning: implicit declaration of function ‘__fpurge’ [-Wimplicit-function-declaration]
__fpurge(stdin);
Para solucionar o problema, basta adicionar no cabeçalho do arquivo:
#include
E voilà! Funciona! :)
Fonte:
http://man7.org/linux/man-pages/man3/fpurge.3.html
12 de julho de 2016 às 12:03
Olá.
Estou com um "pequeno problema" se assim posso dizer
programo c no linux, e obviamente utilizando o compilador gcc,
toda vez que compilo o código onde utilizo o __fpurge dá um aviso de declaração implícita da função, porem funciona, só que me incomoda esse aviso, poderiam me dizer o porque? Ou não tem nenhum problema.
26 de abril de 2017 às 18:28
Show de bola \o/\o/\o/\o/\o/
5 de maio de 2017 às 18:25
Não é recomendado o uso de fflush(stdin), ele é usado para trabalhar com stdout.
Mais aconselhável para limpar buffer de entrar, na maioria dos caso e não todos, é o setbuf(stdin, NULL)
http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1052863818&id=1043284351
25 de maio de 2017 às 15:08
Segundo o pessoal da softblue uma forma de limpar o buffer é criar um ponteiro de char no inicio do programa e cada vez que quizer limpar o buffer é só dar um scanf passando %c &c:
Exemplo:
int main()
{
char *c;
char letra1, letra2;
printf("Insira um caractere: ");
scanf("%c", &letra1);
// limpeza do buffer
scanf("%c",&c);
printf("Insira outro caractere: ");
// limpeza do buffer
scanf("%c", &letra2);
printf("Você digitou: '%c' e '%c'", letra1, letra2);
// é so colar "scanf("%c",&c);" para cada limpeza
scanf("%c",&c);
return 0;
}
scanf("%c",&c);
return 0;
}
Isso faz o terminal "segurar a tela" para leitura no final tb para quem usa visual express como eu.
Caso tenha alguem interessado em aprender c podemos criar um grupo de whats e aprender c juntos.
11 de outubro de 2017 às 16:56
Tamy Caroline, sobre a função rand(), sei q a resposta está meio atrasada, mas o caso da função rand() sempre pensar, ao executar inicialmente um programa, o mesmo valor, se dá por causa da semente que se continua o mesmo. No caso, para o computador mudar a semente, é recomendado que vc utilize o tempo como semente:
#include "stdio.h"
#include "time.h"
#include "stdlib.h"
int main (){
srand(time(NULL)); //mudando a semente para o tempo do computador
//depois vc segue com a função rand normalmente e cada nova execução, ele gerará valores diferentes
[...]
}
4 de junho de 2018 às 13:09
O que o Fabio disse acima está correto. o comando fflush(stdin) não é recomendado para limpar o stdin.
Sugiro o uso do modo como ele fez p limpar o stdin e também deixo duas funções que são ótimas para limpar o stdin:
void limpa_linha() {
scanf("%*[^\n]");
scanf("%*c");
}
ou essa:
void fflush_stdin() {
int ch;
while ((ch = getchar()) != '\n' && ch != EOF);
}
Para usar essas funções, qualquer q seja, é só chamar ela depois de cada scanf e resolve o problema do stdin
21 de junho de 2018 às 06:09
para limpeza segura do buffer usem
while((c = getchar()) != '\n' && c != EOF){}; //sempre após scanf()
inicialize a variável
char c:
20 de agosto de 2018 às 18:19
#include
#include
#include
#include
#include
#include
main (void)
{
setlocale(LC_ALL,"portuguese");
system ("color 3E");
char letra1, letra2;
printf("Insira um caractere: ");
letra1 = fgetc(stind);
fflush(stdin);
printf("Insira outro caractere: ");
letra2 = fgetc(stind);
printf("Você digitou: '%c' e '%c'", letra1, letra2);
}
Só não funcionou com o "fgetc(stind);"
Não entendi porque isso aconteceu. Fiquei a me perguntar se essa função pertence ao linux. utilizo o windows.
12 de setembro de 2018 às 13:13
jean carlos conceição experimente "fgetc(stdin);" stind deve ser uma gralha.
27 de janeiro de 2019 às 12:00
Parabéns pelo criador desse curso. É muito bom mesmo, ensina coisas que nem na faculdade eu vi.
26 de março de 2020 às 10:11