• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

The Loser

scanf - int only

5 mensagens neste tópico

Boas! Estou aqui a dar umas aulinhas ao meu irmão mais novo de C.

E comecei pelo básico, um calculador de factoriais.

No entanto encontro-me com um problema, segue-se o código:

#include <stdio.h>

int factorial(int);
int leitura(void);

int main(void){

    int x = leitura();
    if (!factorial(x)){
        printf("Insira um valor menor, si vous plais.");
        return 0;
    }
    printf("O factorial de %d é %d .", x, factorial(x));
}

int factorial(int x){

    if(x == 1) return 1;
    return x * factorial(x-1);
}

int leitura(){

    int x;
    do{
        printf("Valor: ");
        scanf("%d", &x);
    }while((int)x < 1);
    return x;
}

Isso, obviamente trabalha. O meu problema encontra-se no scanf, pois só quero que o programa aceite inteiros e não "crashe" na leitura de uma string.

Pensei nisto:

while(int y=(scanf("%d",&x)%2)==0){ printf("Valor invalido!"); }

Fiz várias tentativas na base disso.

No entanto isso causou um ciclo infinito em todas as tentativas. :P

Até me sinto envergonhado em pedir ajuda nisto, visto que já trabalho com C há bastantes anos.. No entanto ultimamente não me foi necessário a execução de tal tarefa.

Uma ajuda?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Para além de imprimires a mensagem a dizer que o valor é inválido, limpa também o buffer de input.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Para além de imprimires a mensagem a dizer que o valor é inválido, limpa também o buffer de input.

Haha, não sei como isto me passou ao lado! :D

Muito obrigado Rui Carlos. :P

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

int clear_input(void) {
    int ch;
    while (((ch = getchar()) != '\n') && (ch != EOF)) /* void */;
    return ch;
}

int input() { 
    int x;
    int y;
    do {
        printf("Valor: ");
        fflush(stdout);
        y = scanf("%d", &x);
        clear_input();
        if (y != 1) fprintf(stderr, "Erro. Tenta outra vez\n");
    } while(y != 1);
    return x;
}

A função scanf() devolve um int. Esse int que ela devolve é o número de valores que a função conseguiu meter nas variáveis especificadas.

No teu caso < scanf("%d", &x) >, o scanf() ou devolve 0 (erro) ou 1 (provavelmente tudo bem). A alteração proposta guarda esse valor para sair do ciclo ou apresentar uma mensagem de erro.

Além disso acrescentei a função clear_input() para o scanf() seguinte ter um input 'limpinho'.

Se não se limpar o input e se introduzir, por exemplo, "pmg" para o scanf() ele detecta erro no 'p', o ciclo repete e o scanf volta a detectar erro no 'p'.

No entanto ainda tens um problema com grandes números (que não te afecta neste programa).

Se deres ao scanf() qualquer coisa como 12345678901234567890 ele converte para <não sei quantos>, devolve 1 e, sem o clear_input(), fica com alguns dígitos pendurados. Calculo que isto não te preocupe para já ... mas é sempre bom pensar nisso :P

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Obrigado também pmg. :P

Mas já resolvi. :)

No entanto é bom que me sejam lembrados certos aspectos da linguagem. :D

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora