fflush(stdin);

25. Re: fflush(stdin);

Matheus Pedro
matheusPedro

(usa Debian)

Enviado em 28/04/2015 - 14:19h

Pelo que entendi, seu programa, quer receber numeros enquanto oper for diferente de 0...

Vamos lá!
Parece que seu algoritmo cai em um loop infinito...

#include <stdio.h>

int main()
{
int oper=10; // Aqui você atribui o valor 10 à variável "oper" que é inteira...

while(oper != 0 )// Aqui você diz que o codigo dentro do WHILE deve ser executado enquanto oper for diferente de 0.
//O erro já começa aqui, quando vc definiu oper = 10, isso quer dizer que ele sempre será diferente de 0, logo, vc criou um while infinito...(Claro, há não ser que essa seja sua intenção)
{
printf("\nDigite um numero: ");// O conteudo desse while se torna inutil, ja que seu printf não passa valor pra nenhuma variavel pra contar as vezes e nem pra guardar valor....
fflush(stdin);//A função fflush() com o parametro stdin serve para limpar o buffer do teclado.
}
}


Com base nas informações dadas vamos ao programa correto:


#include<stdio.h>

int main(){
int oper =10, int n;//N é onde vc vai armazenar os numeros...

while(oper != 0){
printf("\nDigite um numero: ");
scanf("%d", &n);//Recebe o numero digitado...
fflush(stdin);//Limpa o buffer do teclado
oper--;//Decrementa de oper
}
system("pause >> log");
}




  


26. Re: fflush(stdin);

Ronaldo Francisco Alves da Silva
ronaldofas

(usa Linux Mint)

Enviado em 31/05/2015 - 15:52h

Pessoal, estou tendo um problema parecido com esse só que no meu caso estou utilizando strings, como faço para limpar corretamente o buffer?

Segue o meu código:
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <string.h>
#include <ctype.h>
#include <stdio_ext.h>

int main (int argc,char *argv[])
{
setlocale(LC_ALL, "Portuguese");
char resp1[30+1], resp2[30+1], troca[30+1];

printf("Digite a primeira palavra até 30 caracteres: ");
scanf("%10[^\n]",resp1);

printf("Digite a segunda palavra até 30 caracteres: ");
scanf("%10[^\n]",resp2);

strcpy(resp1,troca);
strcpy(resp2,resp1);
strcpy(troca,resp2);

printf("Você digitou a palavra %s e a palavra %s\n", resp1, resp2);

// system("pause");
return(0);
}


Desde já agradeço a todos.


27. Re: fflush(stdin);

Thiago Henrique Hüpner
Thihup

(usa Manjaro Linux)

Enviado em 31/05/2015 - 16:25h

Não gosto de "coveiros". Se precisarem de ajuda só criar outro tópico ...

Olha, vou entregar o código, mas isso é errado, mas o pior será para você...


// Pra que tantos includes?
#include <stdio.h>
#include <locale.h>

int main (int argc,char *argv[]) {
setlocale(LC_ALL, "Portuguese");
char resp1[31], resp2[31];

printf("Digite a primeira palavra até 30 caracteres: ");
// Pega ate 30 carateres
scanf("%30[^\n]s",resp1);
// Limpa o Buffer
getchar();
printf("Digite a segunda palavra até 30 caracteres: ");
scanf("%30[^\n]s",resp2);
getchar();

printf("Você digitou a palavra %s e a palavra %s\n", resp1, resp2);

// Não use System Pause!!!
#ifdef WIN32
printf("Pressione [ENTER] para continuar ...\n");
getchar();
#endif

return(0);
}



Espero ter ajudado

[]'s

T+

--

Quantos programadores são necessários para trocar uma lâmpada?
R: Não é possível ser feito. É um problema de hardware.




28. Responder algumas questões

Sullivan Floyd
programadorc

(usa OpenBSD)

Enviado em 17/10/2015 - 09:41h

Sou novo por aqui, mas gostaria de auxiliar em algumas dúvidas.

Primeiro

Vi uma das dúvidas referente a ocorrência de entradas onde limpar o buffer não é necessário em em outros momentos ser. Éo seguinte, a limpeza do buffer se faz necessária sempre que houver a entrada de um ou mais caracteres (dados alfanuméricos). Se for efetuada uma entrada numérica seja int, float ou double o buffer do teclado não fica sobrecarregado. Este efeito é comum em diversas linguagens de programação e não só em C. Em relação a dados do tipo char ocorre que após a confirmação da entrada com a tecla <Enter> o caractere "\0" do <Enter> fica mantido no buffer e desloca automaticamente a próxima entrada, fazendo-a saltar.

Segundo

A limpeza de buffer realizada com fflush() ou __fpurge() apesar de funcionarem não são as melhores formas, são soluções particularizadas parecendo-se com certo tipo de "gambiarra". A forma padrão para limpar buffer que funciona em qualquer sistema operacional deve ser escrita como:

while ((getchar() != '\n') && (!EOF));

A instrução, em si só, é um excelente exercício de percepção lógica do que ocorre com o buffer, devendo ser usada sempre após um scanf(), por exemplo.

Seria propício indicar a leitura e estudo do livro:

Linguagem C acompanhada de uma xícara de café
Autor: José Augusto Manzano
Editora Érica/Saraiva.
Ano 2015.





29. Re: fflush(stdin);

Paulo
paulo1205

(usa Ubuntu)

Enviado em 17/10/2015 - 16:54h

Thiago,

Cuidado, por no seu exemplo você voltou a incorrer num erro que já foi apontado aqui no fórum.

Quando você diz “scanf("%30[^\n]s", array)”, o que você diz é “leia zero ou mais, até um máximo de 30, caracteres que sejam diferentes de '\n' e, após os trinta caracteres ou detectar um '\n', tente encontrar o caráter 's'”. %[ é uma cláusula de formatação própria para leitura de strings, com regras de funcionamento diferentes das de %s. Essa cláusula é iniciada por “%[” e terminada por “]”, e não um modificador da cláusula %s.

Assim, se o usuário digitar “Paulo\n” em resposta à string de formatação que você colocou, a função vai interromper o processamento prematuramente, pois o '\n' vai interromper a leitura da string e vai resultar em falha ao ser comparado com 's', e por isso não é consumido pela função (e é consumido depois pela sua chamada a getchar()).

A única forma de fazer scanf() chegar ao final do processamento com essa string de formatação seria se o usuário digitasse pelo menos 31 caracteres antes da quebra de linha e o 31º caráter fosse um 's'.

Mas e se o usuário digitar mais de 31 caracteres e o 31º caráter não for 's' ou o 32º não for um '\n'? Então sua chamada a getchar() não vai consumir nenhuma quebra de linha, e as demais operações de leitura vão falhar.

Uma forma possivelmente melhor (mas não perfeita) de fazer toda a operação de leitura com scanf() e sem precisar de getchar() seria do seguinte modo.

scanf("%30[^\n]%*[^\n]%*1[\n]", array) 


Essa string lê até 30 caracteres diferentes de quebra de linha e os grava em array. Se houver excedentes, a atribuição para após o 30 caráter e começa a descartá-los, até encontrar a primeira ocorrência de um '\n', que também é descartado.


30. Re: fflush(stdin);

Thiago Henrique Hüpner
Thihup

(usa Manjaro Linux)

Enviado em 17/10/2015 - 17:40h

Caro Paulo, viste quando foi que eu enviei aquela mensagem?

Hoje vejo que está muito incorreto. Obrigadi pelas correções mas agora já sei, mas não quando enviei.

Algum coveiro ressucitou esse tópico :/

Espero ter ajudado

[]'s

T+

--

body@human: $ sudo su
brain@human: # apt-get purge -y windows* && echo "Windows removed successfully"




31. Re: fflush(stdin);

Paulo
paulo1205

(usa Ubuntu)

Enviado em 17/10/2015 - 21:16h

programadorc escreveu:

Sou novo por aqui, mas gostaria de auxiliar em algumas dúvidas.

Primeiro

Vi uma das dúvidas referente a ocorrência de entradas onde limpar o buffer não é necessário em em outros momentos ser. Éo seguinte, a limpeza do buffer se faz necessária sempre que houver a entrada de um ou mais caracteres (dados alfanuméricos). Se for efetuada uma entrada numérica seja int, float ou double o buffer do teclado não fica sobrecarregado.


A coisa é um pouco diferente do que você disse. Permita-me fazer algumas correções.

Em primeiro lugar, é interessante deixar claro que você está falando de leitura com a função scanf() -- que, por sinal é provavelmente _a_ função mais complexa da biblioteca padrão do C. Nesse contexto, é verdade que operações de leitura com conversão de dados numéricos desprezam espaços em branco (incluindo quebras de linha) que antecedam o dado lido. Porém, espaços após o número permanecem no buffer e, portanto, não haverá garantia de buffer limpo após a leitura.

Outro ponto a observar é que é falso dizer que toda entrada de caracteres vai sofrer com problemas de coisas inesperadas no buffer. A conversão %s de scanf() é um exemplo de operação de leitura de texto que executa exatamente o mesmo procedimento de descarte de espaços em branco que as conversões de dados numéricos antes de chegar aos caracteres que vai consumir.

Frequentemente a permanência de caracteres no buffer de entrada após uma operação de leitura é indesejada, e esses caracteres costumam ser chamados de “lixo no buffer de entrada”. Eu considero essa terminologia errônea, porque se um caráter aparece na entrada, não foi por descaso semelhante ao de alguém que joga lixo na rua, mas porque ele foi posto na entrada com alguma finalidade. A própria marca de fim de linha, como exemplo mais evidente, é necessária para que muitas operações de leitura possam ser concluídas.

Um programador pode dizer que essa marca de fim linha e outros caracteres de espaços (ou de outro tipo qualquer) são “lixo” do seu ponto de vista, porque ele não está interessado nela, mas tão somente nos dados que vêm antes ou depois deles. Entretanto, funções como scanf(), fscanf(), fgets() ou mesmo getchar() foram criadas para poder tratar qualquer caso, e não apenas casos específicos de uma pessoa ou outra -- até porque seria impossível prever todos esses casos. O que é lixo para uma aplicação (por exemplo, que extrai apenas um conjunto de números de uma tabela escrita como texto e os usa para computar um resultado final) pode ser um dado crucial para outra aplicação (que, por exemplo, gere a assinatura digital da mesma tabela), e o mesmo conjunto de funções serve para atender as duas.

Para todo programador, em qualquer tipo de aplicação, é essencial conhecer bem como cada função funciona e quais recursos são oferecidos, pois ele terá de ser adaptar a elas (ou mudar de ferramenta).

Este efeito é comum em diversas linguagens de programação e não só em C. Em relação a dados do tipo char ocorre que após a confirmação da entrada com a tecla <Enter> o caractere "\0" do <Enter> fica mantido no buffer e desloca automaticamente a próxima entrada, fazendo-a saltar.


Você se confundiu de novo. O caráter correspondente à tecla ENTER é '\n', não '\0'. O '\0' é usado por convenção nas funções da biblioteca padrão do C para marcar o final de uma string armazenada em memória. O que permanece no buffer de entrada -- quando permanece -- é o '\n'.

Segundo

A limpeza de buffer realizada com fflush() ou __fpurge() apesar de funcionarem não são as melhores formas, são soluções particularizadas parecendo-se com certo tipo de "gambiarra". A forma padrão para limpar buffer que funciona em qualquer sistema operacional deve ser escrita como:

while ((getchar() != '\n') && (!EOF));


Erradíssimo, pois essa condição de controle será sempre falsa (EOF é uma constante com valor -1, logo !EOF vale zero, e qualquer coisa que faça uma operação lógica de “e” com zero dará zero).

Talvez você tenha tentado dizer isto aqui:

int ch;  /* Note que é int, e não char!!! */
while((ch=getchar())!='\n' && ch!=EOF)
;


A instrução, em si só, é um excelente exercício de percepção lógica do que ocorre com o buffer, devendo ser usada sempre após um scanf(), por exemplo.


Falso. Primeiro porque você pode fazer com que scanf() consuma a marca de fim de linha ou outros caracteres que você eventualmente queira descartar.

Segundo porque é possível que o buffer já esteja “limpo” (isto é, pronto para ler uma linha nova), e chamar uma rotina como a acima para esvaziar o buffer, nesse caso, vai começar a suprimir dados novos. Funçõs como fpurge()/__fpurge(), bem como fflush() quando aplicada a stream de entrada, são, sim, gambiarras, mas elas têm condições de examinar internamente as estruturas de controle do stream para saber se ele está no estado consistente antes de começar a descartar coisas; o loop mostrado acima, não, podendo descartar o que não deve e se tornar uma gambiarra ainda pior.


32. Re: fflush(stdin);

Leonardo J. Oliveira
leojuoli

(usa Debian)

Enviado em 19/10/2015 - 19:47h

Embora seu programa aparentemente não precise limpar o buffer, no Linux usamos:
__fpurge(stdin);
--
Leonardo Juoli
fale@leojuoli.com


33. Re: fflush(stdin);

Rennan Weslley
TheMythApple

(usa Ubuntu)

Enviado em 02/02/2017 - 15:13h

Uma solução simples e fácil é botar um espaço antes do % no scanf.

- Sem espaço: scanf("%d", &num);
- Com espaço: scanf(" %d", &num);

Funciona bem.



01 02 03



Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts