Чтение символа с помощью scanf()
Этот код для игры в кости.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
int roll_dice(void);
bool play_game(void);
int main()
{
int i, ch,win = 0,lose = 0;
bool flag;
srand((unsigned)time(NULL));
do
{
flag = play_game();
if(flag)
{
printf("You win!");
win++;
}
else
{
printf("You lose!");
lose++;
}
printf("\n\nPlay again(Y/N)? ");
scanf("%c", &ch);
ch = getchar();
printf("\n");
}while(ch == 'Y' || ch == 'y');
printf("\nWins: %d Losses: %d",win,lose);
return 0;
}
int roll_dice(void)
{
return rand()%6 + rand()%6 + 2;
}
bool play_game(void)
{
int sum = roll_dice();
printf("You rolled: %d\n", sum);
if(sum == 7 || sum == 11)
return 1;
else if(sum == 2 || sum == 3 || sum == 12)
return 0;
else
{
int point = sum;
printf("Your point is: %d\n", point);
do
{
sum = roll_dice();
printf("You rolled: %d\n", sum);
if(sum == 7)
return 0;
}while(point != sum);
return 1;
}
}
У меня проблема только с фрагментом кода
printf("\n\nPlay again(Y/N)? ");
scanf("%c", &ch);
ch = getchar();
printf("\n");
Я использовал, потому что он завершает после одной итерации любой пользовательский ввод Y
или же N
, Я думал, что я делаю неправильно, помещая ch = getchar()
съесть \n
, Я удалил его и поместил пробел перед спецификатором преобразования и заменил его на " %c"
который также не работал. Когда я заменил спецификатор преобразования на %d
это работает отлично.
Что-то не так с этим?
Я посетил этот пост, и он говорит то же самое, что и я.
4 ответа
Размещенный код имеет неопределенное поведение, потому что ch
имеет тип int
и спецификатор формата %c
должен соответствовать char
,
Когда я заменил спецификатор преобразования% d, он работает нормально.
Когда вы переключаетесь на %d
scanf()
не удается, потому что Y
или же y
это не int
таким образом, никакие входные данные не потребляются (кроме начальных пробелов, которые отбрасывают символ новой строки на последующих итерациях цикла) и последующих ch = getchar()
фактически читает введенный пользователем символ, а код работает по счастливой случайности. Всегда проверяйте возвращаемое значение scanf()
, который возвращает количество выполненных назначений.
Вы конвертируете персонажа с scanf
(), а затем перезаписать его getchar
() сразу после этого. Я не ожидал, что это сработает, если вы не введете "yy" перед вводом ENTER, но тогда ваше второе подтверждение не будет выполнено.
Кстати, используйте пространство в " %c"
,
scanf("%c", &ch);
ch = getchar();
И вот как вы потеряли предыдущий символ, хранящийся в ch
, Как насчет
ch = fgetc(stdin);
while (fgetc(stdin) != '\n')
;
вместо?
printf("Play again? ");
scanf(" %c", &char);
этот код работает для меня. Проект взят из книги К-Кинга "Программирование на C: современный подход". Я встречался с этой проблемой раньше, и у меня была такая же проблема. На странице 224 приведен пример проекта guess.c, который включает в себя точно такую же команду "спросить" ("повторить игру"). И автор использовал scanf(" %c", &command); (он использовал команду вместо ch), и это сработало. Я помню, что использовал его во время проекта "игра в кости", но он не работал. Возможно, я что-то пропустил. В целом, выражение выше 100% работает.