1

This question is pretty basic but I couldn't find an answer anywhere so I decided to ask it on here.

Basically I have the following code....

while (scanf(" %*[^\n]%d%c", &a, &c) != 2 || c != '\n' || a > max || a < min) {
    printf("Error! Try again.");
}

...and what I'm trying to do with it is make sure the user gets an error message if they enter an incorrect value, with a new scanf prompt appearing immediately after.

For the most part I've got this loop working, but if I press enter without any other input (leaving only '\n' in the input buffer), the scanf just waits for more input instead of terminating and returning a value. While I understand that it's normal for this to happen if scanf doesn't meet any conditions that let it return to the caller, I've been having a hard time forcing it to terminate with a single newline in its buffer. Here I've assumed that leaving a space before the first format specifier would help (so that a single newline could be ignored), but for whatever reason it doesn't seem to help. Does anybody know how I can fix this while keeping the existing code the same (if at all possible)?

  • It is _possible_ to solve this with `scanf()` and more code, but not worth it. [Use `fgets()`](http://stackoverflow.com/a/33811420/2410359) or perhaps `getline()` if on *nix as the first step. Then `strtol()` or `sscanf()`, etc. Example: http://stackoverflow.com/a/22544609/2410359 – chux - Reinstate Monica Nov 19 '15 at 18:19

1 Answers1

2

You have to change the strategy for dealing with your problem.

  1. Read a line of text using fgets.
  2. Extract the data from the line using sscanf. If the line does not have the data, repeat.
char line[LINE_SIZE];
while ( fgets(line, LINE_SIZE, stdin) )
{
   if ( sscanf(line, "%d", &a) != 1 || a > max || a < min)
   {
      printf("Error! Try again.");
   }
   else
   {
      break;
   }
}

If you want to enforce exactly one number followed by a newline, you can use:

   if ( sscanf(line, "%d%c", &a, &c) != 2 || c != '\n' || a > max || a < min)
R Sahu
  • 204,454
  • 14
  • 159
  • 270