Jump to content

fflush(stdin) necessário?


Recommended Posts

Posted

Boas. É assim, eu considero-me um programador de C com bastantes conhecimentos mas há certos aspectos que tenho algumas dúvidas.

Já vi em alguns tópicos e colegas meus também a utilizam, a instrução fflush(stdin), que serve para limpar o buffer do teclado.

Eu nunca uso essa instrução e acho que são instruções dessas que fazem o código ficar muito extenso. Nunca tive qualquer problema nos programas que fiz...

Mas gostava de seber a vossa opinião, se realmente essa instrução vale a pena e as vantagens/desvantagens da mesma.

"Nunca discutas com um idiota. Eles arrastam-te até ao seu nível e depois ganham-te em experiência"

Posted

A questão nem deve ser se vale a pena, mas sim se funciona. Pelas experiências que tenho feito, essa função não funciona em algumas versões do Linux nem em Mac OS X. No entanto já ouvi várias pessoas dizerem que funciona em Windows.

Mas se funcionasse sempre, por vezes era útil. Assim, normalmente recorro a um ciclo para limpar o buffer.

EDIT:

int fflush(FILE *stream)

On an output stream, fflush causes any buffered but unwritten data to be written; on an input stream, the effect is undefined. It returns EOF for a write error, and zero otherwise. fflush(NULL) flushes all output streams.

Posted

Não fazia ideia que não funcionava em Linux (vou testar daqui a pouco, estou em Windows agora), eu recorro a ela por vezes.

No fundo resolve-te estes casos:

Pretendes ler um inteiro, e uma frase na linha seguinte.

Se fizeres simplesmente um scanf("%d",&i) e um fgets(), o fgets vai "apanhar" somente o '\n'. Com o fflush entre os dois limpas o resto da linha (após o inteiro).

A tua pergunta foi "se vale a pena"? Sei lá. Faz aquilo. Há muitas funções que não uso porque lhes dou a volta. É uma questão de necessidade, não programo a pensar "vou resolver isto com um fflush".

Posted

fflush é uma função muito util, mas normalmente uso-a para limpar o buffer de saida, e não o de entrada. Evita coisas como colocar um "\n" no fim do printf para mudar a linha. isso sim é muito má politica.

Quanto ao funcionar em Linux, nunca tive problemas... tenho de investigar isso...

Posted

Não parece existir qualquer tipo de erro associado ao uso da função fflush em linux, pelo menos pelas mailling list que consultei muito por alto, e as man pages da funcção também não referem nada, tendo em conta que é uma função bastante velha. se alguém tem erros convém verificar a variável 'errno' e as man pages da função 'write' para ver o que aconteceu.

Agora quanto a limpar o buffer de entrada, convém saber que o sistema operativo tem sempre mais que fazer que atender aos pedidos dos programas 😉, e normalmente esses tipo de pedidos são lançados para o buffer e atendidos mais tarde, o que quer dizer que se fizerem duas leituras seguidas pode ocorrer que a segunda leitura pode obter o valor introduzido na primeira.

Isso acontece em várias funções, tais como a função malloc que é uma função optimista. Normalmente dão origem a erros muito dificeis de detectar, resumindo aconselho o uso da função fflush para a leitura, e para tudo o resto.

Posted

Não parece existir qualquer tipo de erro associado ao uso da função fflush em linux, pelo menos pelas mailling list que consultei muito por alto, e as man pages da funcção também não referem nada, tendo em conta que é uma função bastante velha. se alguém tem erros convém verificar a variável 'errno' e as man pages da função 'write' para ver o que aconteceu.

Eu não disse que existia um erro na função. O que eu disse é que essa função não faz aquilo que vocês dizem que faz.

If stream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined.

If stream is a null pointer, the fflush function performs this flushing action on all streams for which the behavior is defined above.

A função fflush destina-se a manipular output streams, e quando lhe dão uma input stream o seu comportamente é indefinido. Aliás, no Mac OS X existe a função fpurge que se destina precisamente a limpar um buffer. Se a fflush fizesse isso, por que razão existiria outra função? Não há nada que nos garanta que a função fflush vá funcionar, pois os standards não obrigam a que tal aconteça.

A citação que eu coloquei foi retirada do seguinte documento: http://www.nirvani.net/docs/ansi_c.pdf

Posted

Tens razão em relação aos standards, mas o habito é uma coisa muito má, e tenho o habito de me referir mais às man pages do que aos documentos standard uma vez que são essas man pages que definem o comportamento da função, é claro que é só para esse sistema/implementação.

Mas também como disse antes normalmente uso a função para limpar o buffer se saida, que é uma output stream. Bem neste caso estou sem argumentos 😉, sempre usei a função fflush com o buffer de entrada quando as leituras estavam a dar problemas e isso resolvia os problemas e ajudava a fazer o debug.

Peace.

  • 1 month later...
Posted

Normalmente o acrescentar de um "getchar();" antes da proxima leitura resolve os problemas todos.

Salvo, é claro, alguns casos especiais, como terem ficado vários caracteres por ler mas isso não é normal acontecer.

A solução de um problema, por mais complicado que seja, tem de ser simples e clara. Caso contrário criamos um novo problema!O caminho mais fácil é muitas vezes o melhor caminho!

Posted

A definição parece mudar conforme a fonte:

http://www.cplusplus.com/ref/cstdio/fflush.html - Em streams de input, limpa o conteúdo do buffer; em streams de output escreve o conteúdo do buffer no destino.

http://man.he.net/man3/fflush - distingue entre o fflush e o fpurge: dizem que o fflush só pode ser usado em outputs e que o fpurge pode ser usado em ambos, tendo as funções fins diferentes. Parece ser esta a definição ANSI C e ISO C.

EDIT: (muito tempo depois) depende do compilador 😄

Desaparecido.

  • 4 years later...
Posted

Ena mais arqueologia 🙂

O que passei a usar e que creio funcionar sempre é o código:

char lixo = '\0';

//....
//depois de uma leitura limpar o buffer
while((lixo = getchar()) != '\n' && lixo != EOF);

Tipicamente tenho esse código em funções de leitura e evito estar a escrever isso constantemente, uso apenas as funções de leitura.

Posted

Podes sempre adicionar um espaço no teu scanf:

Exemplo:

char b;

scanf(" %c",&b);

O espaço que tens entre " e %c faz o mesmo que o fflush mas poupas umas linhas de código e tens compatibilidade em Linux e Windows 🙂

Posted

Podes sempre adicionar um espaço no teu scanf:

Exemplo:

char b;

scanf(" %c",&b);

O espaço que tens entre " e %c faz  o mesmo que o fflush mas poupas umas linhas de código e tens compatibilidade em Linux e Windows 🙂

Isso só funciona para caracteres como o \n, espaço, \t e afins. Não é propriamente uma solução para limpar o buffer de entrada.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.