@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
  • Вопрос задан
  • 78 просмотров
Решения вопроса 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 - там только заглавные буквы. Третий пункт решает эту проблему.
Ответ написан
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы
Технология Екатеринбург
от 100 000 до 200 000 ₽
Кликнет Санкт-Петербург
До 150 000 ₽
Eltex Новосибирск
от 80 000 ₽
31 мар. 2020, в 12:22
1500 руб./за проект
31 мар. 2020, в 12:18
100000 руб./за проект