1
resposta

Barrar letras no scanf, como fazer?

Boa tarde, tudo bem?

Olha só, gostaria de entender como que faço para impedir que o usuário digite letras, símbolos que não são números, ou pelos menos para reescrever com a condição continue;

Vi que tem uma solução no fórum, mas não consegui entender: https://cursos.alura.com.br/forum/topico-o-que-eu-faria-para-invalidar-caso-o-usuario-usa-se-uma-letra-107116. Eu achei muito fraca/vaga a explicação e não consegui compreender como a linguagem lê a condição para barrar as letras digitadas (entendi que só o 1 é considerado número, o resto não)...

Alguém pode me explicar??

Meu código é esse:

#include <stdio.h>
#include <locale.h>
#include <unistd.h>

#define NUMEROS_DE_TENTATIVAS 5

int main(){

    setlocale(LC_ALL, "");

    //imprime o cabeçalho do jogo:
    printf("*******************************************\n");
    printf("* Bem-vindo ao nosso jogo de adivinhação! *\n");
    printf("*******************************************\n");

    int numerosecreto = 42;

    int chute;

    //Esse for é loop para que o jogador tenha só três chances para acertar o número secreto:
    for(int i = 1; i <=NUMEROS_DE_TENTATIVAS; i++){
        printf("Sua %d tentativa de %d no momento\n", i, NUMEROS_DE_TENTATIVAS);
        printf("Tu sabe qual é o número que o jogo pensou?");
        scanf("%d", &chute);

        //Quando o jogador tentar colocar número negativo:

        if (chute < 0){
            printf("Amigue, tudo não pode chutar com números negativos.\n");
            i--;
            continue;
        }

        //Continuação do loop:

        printf("Então tu acha que o número que jogo tem guardado é %d?\n", chute);
        system("pause");
        printf("Vou ver ser é verdade...\n");
        sleep(2);

        //Verificação se o jogador adivinhou o número secreto:

        int acertou = (chute == numerosecreto);
        int chutemaior = (chute > numerosecreto);
        int chutemenor = (chute < numerosecreto);

        if(acertou){
            printf("Parabéns!! Tu acertou o número que o jogo pensou!\n");
            printf("Quer jogar mais uma vez?\n");
            break;
        }
        else{
            printf("Hmmm... Você errou o número que jogo pensou...\n");
            printf("Mas não desanime. Tente de novo!\n");


            if (chutemaior){
                printf("Dica: o seu chute foi maior que o número pensado pelo jogo.\n");
            }

            else if (chutemenor){
                printf("Dica: o seu chute foi menor que o número pensado pelo jogo.\n");
            }        
        }
    }
    printf("Fim de jogo!!\n");
    system("pause");
}
1 resposta

Boa noite, Rodrigo. Vou tentar esclarecer suas dúvidas.

Eu achei muito fraca/vaga a explicação e não consegui compreender como a linguagem lê a condição para barrar as letras digitadas (entendi que só o 1 é considerado número, o resto não)...

No caso da resposta do tópico, o valor retornado pelo scanf() é a quantidade de valores convertidos com sucesso para o tipo inteiro(ou para qualquer formato que você passar como parâmetro para o scanf). Como seu input prevê a entrada de 1 valor apenas, então o valor de retorno do scanf() precisa ser igual a 1.

Neste caso, a condição (scanf() != 1) é suficiente. Entretanto uma solução mais refinada é checar se o inteiro é seguido por um caracter("%d%c"), e caso o caracter for igual a '\n', o input é válido.

Cheque aqui o código.