C - попытка считать единственный символ из stdin (и сбой) w/scanf / getchar

как часть присвоения домашней работы, я пытаюсь считать единственный символ из stdin и действие согласно ему:

char choice;

while (1) {
    printf("please enter [y]es, [n]o or [m]aybe: ");
    scanf("%c", choice);
    fflush(stdin);
    // validate input
    if (choice == 'y' || choice == 'n' || choice == 'm') {
        break;
    } else {
      printf("Please enter only \'y\', \'n\' or \'m\'!\n");
    }
}
// do something with the input
if (choice == 'y') {
    printf("you selected yes!\n");
}

по некоторым причинам scanf получает и символ и перевод строки после, таким образом он продолжает делать что-то с входом и затем также печатает, "Войдите только 'y', 'n' или 'm'!" строка. Если я введу несколько символов в stdin, то он распечатает ту строку для всех них, также работая правильно для первого символа. Так, например:

$ ./run
please enter [y]es, [n]o or [m]aybe: y<return>
you selected yes!
Please enter only 'y', 'n' or 'm'!
$ ./run
please enter [y]es, [n]o or [m]aybe: yes<return>
you selected yes!
Please enter only 'y', 'n' or 'm'!
Please enter only 'y', 'n' or 'm'!
Please enter only 'y', 'n' or 'm'!
$

То же самое происходит, если я использую getchar. Что я пропускаю?спасибо.

5
задан Iharob Al Asimi 14 November 2015 в 14:41
поделиться

3 ответа

Для корректной работы вам нужно пространство между scanf(" и %c:

scanf(" %c", &choice);

А еще вам нужно использовать &choice, а не выбор!

EDIT: Пока вы этим занимаетесь, вы, возможно, захотите просмотреть do while() для этого цикла (если только профессор специально не сказал использовать break) - do while работает отлично при проверке пользовательского ввода!

.
9
ответ дан 18 December 2019 в 10:45
поделиться

fflush() не определено ISO для входных потоков. Оно определено в библиотеке времени исполнения Microsoft C, но не переносится.

Хотя решение "пробел перед %c" может сработать, когда пользователь вводит ожидаемые данные, оно не сработает во многих отношениях; попробуйте, например, ввести "y n y n". Консольный ввод ориентирован на lin; лучше всего убедиться, что вы отбрасываете всю строку так:

scanf( "%c", choice ) ;
while( choice != '\n' && getchar() != '\n' ) /* do nothing*/ ;
4
ответ дан 18 December 2019 в 10:45
поделиться

Лучше использовать fgetc(). scanf() всегда должна быть последним средством.

3
ответ дан 18 December 2019 в 10:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: