Why I'm getting unexpected result from strcmp function in c

99 views Asked by At

I have made a game and this is the last part when a player is required to type yes/no to paly again. But the result of this code is unexpected. Code:

do{
    setbuf(stdout, NULL);
    printf("\nDo you want to play again(yes/no)");
    scanf("%s", &yn);
}while(strcmp(yn, "yes")==0||strcmp(yn, "no")==0);

Result:

Do you want to play again(yes/no) no
Do you want to play again(yes/no) yes
Do you want to play again(yes/no) random
Do you want to play again(yes/no)

Its repeating over and over.

Can you fix this code?

1

There are 1 answers

0
Allan Wind On BEST ANSWER
  1. strcmp(yn, "yes")==0||strcmp(yn, "no")==0 evaluates to true if yn is "yes" or "no" so that would explain the first two tests. You probably want:
do {
// ...
} while(!strcmp(yn, "yes"));
  1. It does not explain the 3rd test "sjsbs". This probably means scanf("%s", &yn); failed. You should check the return value.

  2. You did not tell us what yn is but it should be a array so leave out the '&'. It would be particular bad if it's a char yn (see buffer overflow later).

  3. Whenever reading a string with scanf()**always** specify the maximum field width to avoid buffer overflow. If the input is smaller than what is being read byscanf()then a subsequent call would return that. Consider usingfgets()instead ofscanf(). You may still get partial input but with a sufficiently large buffer it will mostly just work. The other option is discard everything in the input buffer till you hit a newline or EOF (using getchar()` for instance).

char yn[3+1];
// ...
if(scanf("%3s", yn) != 1) {
    printf("scanf failed\n");
    break;
}
  1. Use constants instead of magic values especially related ones 3+1 and 3. You seem new at this so don't worry about this quite yet but this is how you would fix that:
#define YN_LEN 3
#define str(s) str2(s)
#define str2(s) #s

// ...

char YN[YN_LEN+1];
// ...
if(scanf("%" str(YN_LEN) "s", yn) != 1) {
// ...
  1. I encourage you to format your code consistently (do { and } while should be at the same level, and I prefer compact code so more of it fits on the screen t a time (i.e. remove all those blank lines).