1
votes

Here is my code to repeatedly read three variables separated by whitespace from user. The format of input should be 'char int int'(e.g b 3 3 ). I use the return value of scanf function to ensure input is exactly three variables.

#include <stdio.h>

int main(void){
  int x, y, nargs;
  char command;

  while(1){
    nargs = scanf("%c %d %d", &command, &x, &y);
    printf("%d\n",nargs);

    if(nargs != 3){
      printf("error\n");
      break;
    }
  }
  return 0;
}

Input and Output:

g 4 4
3
b 3 3
1
error

The first line input is no problem. But when I input second line, it shows scanf() only read one variable from this line. What's the problem of my code?

2
" %c%d%d" is the quick answer. Using fgets() and then sscanf(buf, " %c%d%d",... is better. GTGchux - Reinstate Monica

2 Answers

2
votes

The problem is the \n newline hidden between the two input lines you are sending to stdin. After first scanf you have a '\n' pending on the input stream, then you append "b 3 3" so the whole buffer looks like "\nb 3 3".

Then scanf is called again and \n is matched to %c, after scanf expects whitespace but the buffer has 'b' so it fails after assigning \n to command.

You could try matching with

nargs = scanf("%c %d %d ", &command, &x, &y);
                       ^

so that newline is eaten with the previous scanf, from cppreference:

any single whitespace character in the format string consumes all available consecutive whitespace characters from the input

-2
votes
nargs = scanf("%1s %d %d", &command, &x, &y);

The problem is with the %c for one character. If you change it for %1s you expect an string of one character (the same) but without problems.

With the %c it is better to send the result to an array, and access the content with its index.