@Redproxima
Студент технического ВВУЗ'а

Как реализовать проверку на вводимые символы?

Есть участок кода, в котором я ожидаю от пользователя подтверждения в виде 'Y'/'y' или 'N'/'n'. Перепробовал кучу вариантов, от getch до scanf() совместно с fflush(stdio) в разных циклах и их комбинациях. И всегда программа частично работает, но с подвохом. В частности: в нижеприведенной реализации я хоть и добился того, что проверка реагирует на 'Y'/'y' или 'N'/'n', но делать она это может, например, и при вот таком вводе: "polniyBred". (наткнулась на y в 6 позиции). Честное слово, я прекрасно понимаю, что проблема во мне, что я не совсем соображаю уже в 2 часа ночи, что я не знаю и 10% функций стандартной библиотеки. Поэтому прошу сжалиться и показать, как канонично пишутся такого рода проверки и пользовательские диалоги, избегая по возможности костылей и изоленты. Вы же все сталкивались с такими программами, которые не позволяют вам ввести чушь.
Код
void usrSettings(struct usrSettings_str **usrSet){
    char consent;

    printf("Before changing the settings, read the command manual .help\n");
    printf("Are you sure? (Y/y(for 'Yes') or N/n(for 'No' - setting by default)\n");

    scanf("%c", &consent);
    while(consent != 'Y' && consent != 'y' && consent != 'N' && consent != 'n'){
        printf("Enter Y/y or N/n\n");
        printf("> ");
        scanf("%c", &consent);
    }

    if (consent == ('Y' || 'y'));{
        //Edit somethings settings
        printf("User enter Yes\n");
    }
    
    if (consent == ('N' || 'n')){
        //Return to main menu
        printf("User enter NO\n");
    }
}


В общих чертах, я понимаю, что решение должно быть банальным, но чем дольше я копаю, тем сильнее зарываюсь. Вот, например, scanf() отработала в цикле 4 раза (видать, брала символы из буферизированного ввода), до тех пор, пока не повстречала 'y'. (скриншот 3).
Скриншот 1 (Казалось бы...)
5e77f0f6a53c1097991441.png

Скриншот 2 (Вот тут начинается)
5e77f13697864488128697.png

Скриншот 3 (Полный абзац!)
5e77f20eb1a9a652775612.png
  • Вопрос задан
  • 1745 просмотров
Решения вопроса 1
CityCat4
@CityCat4
Внимание! Изменился адрес почты!
Использовать fgets() чтобы забрать весь юзерский ввод (чтобы избежать повторного чтения).

#define BUFLEN 80
char *str;

str = (char *) calloc(BUFLEN, 1);

    printf("Before changing the settings, read the command manual .help\n");
    printf("Are you sure? (Y/y(for 'Yes') or N/n(for 'No' - setting by default)\n");

for(;;)
 {
    fgets(str, BUFLEN, stdin);
    *(str + 1) = '\0';
    
    if ((*str == 'Y') || (*str = 'y'))
      {
         // Делаем что-то
        break;
      }
    else
       {
          // Сообщаем юзеру, что он чудак, снова даем приглашение на ввод
          bzero(str, BUFLEN);
       }
}

free(str);


Это если нужно разбирать только ситуацию "y" - да, все остальное - нет. Если нужно разобрать 'y' - да, 'n' - что-то еще, остальное - юзер чудак - добавить еще один if после проверки на 'y'
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@Karpion
1) Не видно текст программы - работа программы закрывает его.

2) Вместо scanf("%c",&consent); лучше использовать consent=grtchar();

3) Для данной ситуации сравнения с буквами - хорошо бы делать consent=grtchar()|32; Тогда надо сравнивать с маленькой буквой.

4) consent надо делать int, а не char - там м.б. EOF.

5) Я бы заменил while на do..while или на repeat..until, оно тут логичнее, ибо условие можно проверить только после первого выполнения тела цикла - Вы же написали его дважды, что создаёт возможность мерзких ошибок по невнимательности.

6) Изучите операторы break (выход из тела цикла) и continue (переход к следующей итерации). Тогда оба ифа вносим в тело цикла, дописав к ним break - и не надо дублировать условия.

7) А конкретно у Вас ошибка в условии while - там только заглавные буквы. Третий пункт решает эту проблему.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы