Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading character with scanf()

This code is for game of craps.

#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;
   }                    
}

I have problem only with code snippet

 printf("\n\nPlay again(Y/N)? ");
 scanf("%c", &ch);
 ch = getchar();
 printf("\n");

I have used, because it terminates after one iteration whatever user input Y or N. I thought I am doing wrong by placing ch = getchar() to eat up \n, I removed it and placed a space before conversion specifier and replaced it by " %c" which also did't work.When I replaced the conversion specifier by %d it works fine.
Is anything going wrong with this?
I visited this post and it is saying same thing I did.

like image 714
haccks Avatar asked Dec 15 '22 08:12

haccks


1 Answers

The posted code has undefined behaviour because ch is of type int and the format specifier %c must match a char.

When I replaced the conversion specifier %d it works fine.

When you switch to %d the scanf() fails, because Y or y is not an int, so no input is consumed (apart from leading whitespace which discards the new line character on subsequent iterations of the loop) and the subsequent ch = getchar() actually reads the user entered character, and the code works by fluke. Always check the return value of scanf(), which returns the number of assignments made.

like image 134
hmjd Avatar answered Dec 27 '22 10:12

hmjd