1

I am relatively new to C, but I have been programming for a few years now.

I am writing a program for a college class, and I am confused why the scanf function below is not called, resulting in an infinite loop.

I have tried having my scanf outside the function, calling it twice, once from within, once from out, and a few other ways. I read online that the fflush might help, but it hasn't

Any suggestions?

// store starting variables
int players;

// print title

printf("*------------------------------------*\n");
printf("|                                    |\n");
printf("|                Wheel               |\n");
printf("|                 of                 |\n");
printf("|               Fortune              |\n");
printf("|                                    |\n");
printf("*------------------------------------*\n");
printf("\n\nHow many players are there?: ");

while(scanf("%d", &players) != 1 && players >= 0) {
    printf("That isn't a valid number of players. Try again: ");
    fflush(stdin);
}

EDIT JUST REALIZED I FORGOT TO MENTION SOMETHING. This program works perfectly when I enter an actual number. I want to make it safe for if the user enters something that isn't a string, it won't cause the program to loop infinitely.

2
  • 2
    Do not fflush(stdin). Commented Sep 29, 2015 at 17:01
  • 3
    the logic looks wrong... did you mean while(scanf("%d", &players) != 1 || players <= 0) { (loop if either scanf() fails or there are no players)? Also, fflush(stdin) doesn't clear the input stream on all platforms, so make sure it works on yours before relying on it. Commented Sep 29, 2015 at 17:01

2 Answers 2

3

Likely non-numeric input is in stdin. OP's code does not consume that. Result: infinite loop.

Better to use fgets().

Yet if OP is determined to use scanf(), test its output and consume non-numeric input as needed.

int players;
int count;  // Count of fields scanned
while((count = scanf("%d", &players)) != 1 || players <= 0) {
  if (count == EOF) {
    Handle_end_of_file_or_input_error();
    return;

  // non-numeric input
  } else if (count == 0) {
    int ch;
    while (((ch = fgetc(stdin)) != '\n') && (ch != EOF)) {
      ; // get and toss data until end-of-line
    }

  // input out of range
  } else {
    ; // Maybe add detailed range prompt
  }  
  printf("That isn't a valid number of players. Try again: ");
}
Sign up to request clarification or add additional context in comments.

1 Comment

I don't believe that there is a 100% certitude tu use fgets instead of scanf. The only problem with scanf is that is used almost always wrong.
2

Use fgets to retrieve the input as a string and sscanf to convert it to a number. What this does is prevent errors in conversion from preventing reading from stdin. You could print the values of scanf return code and players to see what you are really receiving. You should also check for end of file which would also cause an infinite loop since there will not be any more input from EOF.

3 Comments

scanf has always tried to do too much and has befuddled too many beginners. fgets and sscanf has always had a better separation of mechanisms.
I have done that actually. My scanf returns 0 every time.
What is the input to scanf? 0 means it doesn't match the formatting string.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.