-1

I am fairly new when it comes down to C programmming. That's why i am working my way up by doing some of the easier exercises. The exercise i'm working on is the "guess the number" game, where the user must guess the number that lies between two numbers (upper and lower bounds). The program is doing what it must, with one exception: when the user enters a character instead of an integer, the program gets stuck in an infinite loop. The only way to break out of this loop is by using a break statement and restarting the program. What i want instead, is to have the program request for the users input again, untill an integer is entered.

Can someone tell me why the programm gets stuck in this infinite loop and why it is not requesting for input again trough scnanf like it did in the first iteration? your help will be appreciated. thank you.

//globals
int secret_nr;
int guess;
int upper_bound = 100;
int lower_bound = 1;
int total_guesses = 1;


void check_input(void) {
    if (guess < lower_bound || guess > upper_bound) {
        printf("Invalid input! Your guess must be between %d and %d\n", lower_bound, upper_bound);
    }
    else if (guess < secret_nr) {
        printf("Higher\n");
        total_guesses++;
    }
    else if (guess > secret_nr) {
        printf("Lower\n");
        total_guesses++;
    }
    else if (guess == secret_nr) {
        printf("correct! You guessed the number after guessing %d times!\n", total_guesses);
    }
}


int main(int argc, char* argv[]) {
    srand(time(NULL));
    secret_nr = (rand() % upper_bound) + 1;

    printf("Guess the number between %d and %d:\n", lower_bound, upper_bound);
    do {
        if (scanf("%d", &guess)) {
            check_input();
        }
        else {
            printf("Invalid input! Only integer values are allowed!\n");
            //break;
        }
    } while (guess != secret_nr);

    return 0;
}
  • 2
    Possible duplicate of [How to loop scanf\_s() until success?](https://stackoverflow.com/questions/50840130/how-to-loop-scanf-s-until-success) – Yunnosch Sep 12 '18 at 07:02

2 Answers2

2

If scanf fails to parse its input according to the specified format, then the input will be left in the input buffer for the next call to scanf which will read the very same input and again fail. And so on and on and on...

The simple solution is to first of all read the whole line of input, using e.g. fgets. Then you can use sscanf in that (now extracted) input to attempt to parse it.


Further complicating your current code is the fact that if scanf fails in some other way, it will return EOF which is the integer -1, which is "true". That will of course lead to problems with your logic and looping as well.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
1

I see this reply in another post: https://stackoverflow.com/a/1716066/5687321

scanf consumes only the input that matches the format string, returning the number of characters consumed. Any character that doesn't match the format string causes it to stop scanning and leaves the invalid character still in the buffer. As others said, you still need to flush the invalid character out of the buffer before you proceed. This is a pretty dirty fix, but it will remove the offending characters from the output.

char c = '0';
if (scanf("%d", &number) == 0) {
  printf("Err. . .\n");
  do {
    c = getchar();
  }
  while (!isdigit(c));
  ungetc(c, stdin);
  //consume non-numeric chars from buffer
}