Lock letters and special characters

Asked

Viewed 2,122 times

0

Good afternoon. I am developing a program in C and have to deal with when the user type letters or special characters. It turns out that when I test by typing a letter, the program loops, kind of flashing on the screen. I wanted to know how to treat it. Thank you

int main(){
int opcao_menu;
while(opcao_menu != 5){
printf("\nEscolha sua opção:\n\n\n
        1 - ...\n
        2 - ...\n
        3 - ...\n
         printf...
         printf("\n\n5 - Sair");
         printf("\n\n\nSua escolha: ");
         scanf("%d", &opcao_menu);
system("cls");
            printf("Opcao invalida!\n");
    }
    return 0;
}
  • nor does it compile

2 answers

2


The truth is, although practice has shown that the function printf() is quite useful for multiple purposes, unfortunately the function scanf() it’s not that useful. Particularly, it doesn’t handle entries as well outside of the expected pattern, as you might check.

In this case, the standard recommendation of experienced C users is to get the entire line for a buffer using fgets() (never gets()) and then analyze the input, possibly using sscanf() for this. For example:

int
main(int argc, char ** argv) {
    static char buffer[1024];
    int opcao_menu = 0;

    while (opcao_menu != 5) {
        // Literais de string uma após a outra são concatenadas
        // Útil para escrever strings longas
        fputs("\nEscolha sua opção\n\n\n"
              "1 - ...\n"
              "2 - ...\n"
              "3 - ...\n"
              "4 - ...\n"
              "5 - Sair\n"
              "\n\nSua escolha: ", stdout);
        // Obtém a linha que o usuário digitou até o [Enter]
        fgets(buffer, sizeof(buffer), stdin);
        // Tenta extrair um número do buffer e verifica os limites do número
        if ((sscanf(buffer, "%d", &opcao_menu) < 1) ||
            (opcao_menu < 1) ||
            (opcao_menu > 5)) {
            system("cls");
            fputs("Opção inválida!\n", stdout);
        } else switch (opcao_menu) {
            // Aqui tratamos os diferentes casos,
            // tipicamente chamando uma função para fazê-lo
            case 1: do_1(); break;
            case 2: do_2(); break;
            case 3: do_3(); break;
            case 4: do_4(); break;
            case 5: fputs("Até mais!\n", stdout); break;
        }
    }

    return 0;
}
  • Sorry, the lack of attention sucks -- fgets has to read from stdin, not of stdout. As for the complexity of the solution, welcome to the world of C. Over time, you learn to package common tasks into library functions that you reuse, or better yet, reuse a third-party written library, such as ncurses...

  • I changed the example by compiling and performing some tests before (for that, I needed to create small functions to handle options 1 to 4 above, but this is beyond the scope of the question). If you try to copy the code one more time, it should work.

1

Try to validate if the size of the input exceeds the allowed 1 digit, taking the size with a function, or if the first pos of the is not a digit.

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int tam(char *s) {
    int cont = 0;
    while(*s++) {
        ++cont;
    }
    return cont;
}

int main()
{

    char opc[1024];

    do {

        printf("\nEscolha uma opcao\n");
        printf("0: Sair\n");
        printf("1: Exibir msg 1\n");
        printf("2: Exibir msg 2\n");
        printf("Opcao: ");
        fgets(opc, sizeof(opc), stdin);
        opc[tam(opc) - 1] = 0;
        if(!isdigit(opc[0]) || tam(opc) > 1) {
            printf("Entre com um digito entre 0 e 2\n");
        }

        else {
        int numero = atoi(opc);
        switch(numero) {
            case 0: exit(0);
            case 1:
                puts("Ola");
                break;
            case 2:
                puts("Oi");
                break;
            default:
                printf("Opcao Invalido\n");
                break;
        }
      }
    }while(1);

    return 0;
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.