Как запретить пользователю вводить нечисловые символы? - PullRequest
0 голосов
/ 20 мая 2019

Привет, пожалуйста, посмотрите на этот код:

while (cont == 1) {
    ...

    scanf_s("%d", &input);

    if (0 < input <= 5){
        switch (input) {
        case 1:
            printf("1");
            break;
        case 2:
            printf("2");
            break;
        case 3:
            printf("3");
            break;
        case 4:
            printf("4");
            break;
        case 5:
            cont = 0;
            break;

        default:
            printf("Wrong input !");
            break;
        }

    }else{
        printf("Error, Not a number !");
    }
}

Если я введу что-то, что не является числом, это приведет к бесконечному циклу. Как мне ограничить ввод символов?

Ответы [ 2 ]

0 голосов
/ 20 мая 2019

После сбоя scanf_s() необходимо прочитать хотя бы один символ (символ, на котором он произошел сбой); обычно имеет смысл отбросить оставшуюся строку, введенную пользователем:

while (cont == 1) {
    int rc;

    ...

    if ((rc = scanf_s("%d", &input)) < 0)
    {
        printf("EOF detected\n");
        break;
    }
    if (rc == 0)
    {
        int c;
        while ((c = getchar()) != EOF && c != '\n')
            ;
        printf("Error, Not a number!\n");
        continue;     
    }

    if (0 < input <= 5){
        switch (input) {
        case 1:
        case 2:
        case 3:
        case 4:
            printf("%d", input);
            break;
        case 5:
            cont = 0;
            break;
        default:
            printf("Wrong input (1-5 required)!\n");
            break;
        }
    }
}

Если EOF обнаружен в цикле 'gobble', вы можете обнаружить EOF там и повторить печать и немедленно прервать цикл. OTOH, следующий scanf_s() должен также сообщить EOF, так что в этом нет необходимости на 100%. Это немного зависит от того, где происходит подсказка; если вы получаете EOF, вы, вероятно, не должны снова запрашивать, поэтому, возможно, тест после внутреннего цикла while должен быть:

if (c == EOF)
{
    printf("EOF detected\n");
    break;
}
else
{
    printf("Error, not a number\n");
    continue;
}

Вы можете поиграть с вариантами цикла 'gobble', которые читают до новой строки или цифры, и используйте ungetch(c, stdin);, чтобы вернуть цифру во входной поток для следующего вызова к scanf_s() для обработки - вы, вероятно, не будет запрашивать больше ввода, если вы собираетесь обработать уже введенную цифру (это может привести к путанице).

Есть бесконечные другие игры, в которые вы можете играть. Один из вариантов, который следует рассмотреть, - это ограничение количества неудачных вводов перед тем, как вы откажетесь - если пользователь не ввел правильное число в 10 попытках, он, вероятно, не собирается.

Обратите внимание, как обработка ошибок сообщает пользователю, каков допустимый диапазон чисел; это помогает им понять это правильно. Также обратите внимание, что в конце сообщения есть новая строка; это вообще хорошая идея. В контекстах вне интерактивного ввода-вывода новая строка может помочь обеспечить вывод выходных данных при печати, а не произвольное время спустя, когда какой-либо другой вывод добавляет новую строку или если буфер вывода заполняется, а ожидающие данные сбрасываются в конце концов.

0 голосов
/ 20 мая 2019

Вы можете использовать это:

if(scanf_s("%d", &input) != 1) {
    printf("Wrong input !");
    break;
}

Вы должны ВСЕГДА проверять возвращаемое значение scanf_s в любом случае.

...