paulo1205
(usa Ubuntu)
Enviado em 10/04/2014 - 13:59h
A dificuldade não é com o
while , mas sim o velho problema de “lixo” no buffer de entrada, com a solução imperfeita (e, no seu caso, colocada no lugar errado) de usar “
fflush(stdin) ”.
Abaixo, eu listo quatro formas alternativas de consertar ou contornar o problema.
1) mover o famigerado
fflush(stdin) para o ponto certo do código (a saber: depois da chamada a
scanf () e antes do próximo
fgets ());
Eu chamo de "famigerado" porque é uma solução que não tem garantia de funcionar. O padrão do C só define o comportamento de fflush () para streams de saída, e stdin é um stream de entrada. Vários sistemas, incluindo versões antigas do Linux, não suportam fflush(stdin) , e mesmo as versões que o suportam o fazem por causa da compatibilidade com antigos compiladores para MS-DOS de uma época anterior ao primeiro padrão do C, a qual eu considero também inadequada.
2) colocar “
scanf(" ") ” antes da chamada a
fgets () (mas tem o problema de que você não vai conseguir ler uma mensagem começando com espaços, nem uma mensagem vazia);
3) usar de modo mais completo a função
scanf () (que é uma função muito complexa, cuja documentação precisa ser muito bem lida para que se possa fazer dela bom proveito), testando seu valor de retorno (algo que sempre deveria ser feito!) e fazendo-a detectar e desprezar dados inválidos na entrada;
int cont;
int a, b;
printf("Deseja continuar (1=sim, 2=nao)? ");
if(scanf("%d%n%1*[\n]%n", &cont, &a, &b)==1 && b>a){
/* leitura bem sucedida e quebra de linha ja consumido */
/* ... algum codigo usando o valor lido de ‘cont’ ... */
}
else{
/* leitura falhou por algum motivo */
/* ... algum codigo para tratar a falha ... */
}
4) ler sempre linhas inteiras como strings, e extrair informações a partir da linha lida com a função
sscanf ().
int cont;
char line[MAX_LINE_SIZE];
printf("Deseja continuar (1=sim, 2=nao)? ");
if(fgets(line, MAX_LINE_SIZE, stdin)!=NULL && sscanf(line, "%d", &cont)==1){
/* leitura bem sucedida */
}