Чтение символа с помощью 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% работает.

Другие вопросы по тегам