Problemas com o esqueleto

Problemas com o esqueleto

por Vinícius Daros -
Número de respostas: 11
    Saudações,

    Estou usando o esqueleto2.c como base para meu EP. Estava tudo funcionando direitinho até que eu fiz as funções de filtro e salvar arquivo. Depois que o programa executa uma dessas funções, ele imprime duas vezes na tela o menu de opções.

    Alguém sabe como resolver isso?

    Abraços,

    Vinícius
Em resposta à Vinícius Daros

Re: Problemas com o esqueleto

por Andrew Kurauchi -
Eu estou tendo exatamente o mesmo problema!!!

Mas não faço a mínima idéia de como resolver isso!

Seria algum problema com o fork?

Abraços,

Toshi
Em resposta à Vinícius Daros

Re: Problemas com o esqueleto

por Vinícius Daros -
    Saudações, pessoal

    Fui tirar essa dúvida com o professor e ele disse que essa dupla impressão do menu se deve ao fato de, após entrarmos com os parâmetros para a função chamada, fica sobrando no buffer de entrada um '\n'. Segundo ele, bastaria colocar um " " (espaço) depois do %d dos scans, ou seja:

scanf("%d", &p);    --> passaria para -->    scanf("%d ", &p);

    Mas, infelizmente, isso gerou alguns outros problemas.

    Assim, tive que fazer uma "gambiarra", que, apesar de ser uma solução feia, funciona perfeitamente. A idéia consiste em pegar esse '\n' que está sobrando e jogar em uma variável inútil, a fim de liberar o buffer de entrada. Ficou assim:

    char lixo;
   
    printf("Digite a semi-variacao horizontal: ");
    scanf("%d", &p);
    printf("Digite a semi-variacao vertical: ");
    scanf("%d", &q);

    scanf("%c", &lixo);

    Espero ter ajudado, mas, se alguém achar uma solução melhor, agradeceria.

    Abraços,

    Vinícius
Em resposta à Vinícius Daros

Re: Problemas com o esqueleto

por Victor Harada -
acho que uma solução melhor do que usar uma variável lixo é usar o comando fflush(stdin) que limpa o buffer do teclado, jogando fora toda a entrada depois dos dados que vc quer ler, ou usar um getchar() sem atribuir o valor retornado para nenhuma variável.
Em resposta à Victor Harada

Re: Problemas com o esqueleto

por Caio Braz -
O fflush(stdin) não funcionou aqui... continuou dando o mesmo problema.
Ja a variavel lixo funcionou perfeitamente!
Em resposta à Caio Braz

Re: Problemas com o esqueleto

por Francisco Reverbel -
A função fflush(FILE *arq) descarrega em arq as escritas que estejam pendentes. Não faz sentido chamá-la para a entrada padrão (stdin), pois não se escreve em stdin.

Só se deve dar fflush em arquivos abertos para escrita. Uma chamada fflush num arquivo aberto só para leitura (como é o caso de stdin) devolve uma indicação de erro (EOF).

Para mais informações: man fflush.

Em resposta à Vinícius Daros

Re: Problemas com o esqueleto

por Francisco Reverbel -
Quais foram os outros problemas gerados pela leitura com "%d "?

O ruim da solução com scanf("%c", &lixo) e da solução com getchar() (sugerida pelo o Victor) é que essas soluções só pegam um caracter extra, que deve ser o newline digitado pelo usuário. Elas não resolvem o problema de um usuário mais chato, que resolve digitar espacos antes do newline.

Digite a semi-variacao vertical: 2[espaço][espaço][espaço][espaço][newline]

O scanf("%d ", &alguma_variavel) (com um espaço depois do d) deveria comer também esses espaços:

    do {
        printf("Digite a semi-variacao vertical: ");
    } while (scanf("%d ", &semi_variacao_vertical) != 1);

Uma outra solução é ler a linha inteira com fgets e depois usar sscanf para pegar o dado da linha lida:

    do {
        printf("Digite a semi-variacao vertical: ");
        fgets(line, MAX_LINE, stdin);
    } while (sscanf(line, "%d", &semi_variacao_vertical) != 1);
Em resposta à Francisco Reverbel

Re: Problemas com o esqueleto

por Caio Braz -
Professor, o erro quando se usou o "%d " foi que o usuario digita e aperta enter, ai ele fica esperando uma nova entrada (um numero, letra ou espaço que seja) pra continuar a execução do programa.
Em resposta à Caio Braz

Re: Problemas com o esqueleto

por Francisco Reverbel -
É verdade, estou vendo isso aqui. O scanf("%d ", &alguma_variavel) só volta para o chamador depois que for digitada a próxima entrada diferente de whitespace (não pode ser espaço nem tab nem newline) ... Ou seja, a minha sugestão do "%d " não funciona!

O jeito é dar um fgets e depois um sscanf, como indicado acima. Isso funciona, certo?