C - fscanf in while loop skips user input

2019-08-14 20:39发布

问题:

So I run the program, it does the prints, reads the char I type from the keyboard, switches to the appropriate case, but instead of returning to the top of the loop and stopping at the fscanf in order to receive further input, it acts like it already received a new line or something and switches to the default case, returning to the top of the loop again and expecting input. What am I missing ?

Here is the code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main () {
  char *command;
  command = malloc (2);

  while (1) {
    printf ("Type help for usage\n");
    printf ("Enter command: \n");
    fscanf (stdin,"%c",command);

    switch (command[0]) {
      case 'a':
        printf ("a\n");
        break;

      case 'h':
        printf ("help\n");
        break;

      default:
        printf ("default\n");
    }
  }
  return 0;
}

回答1:

That's because when you enter a, you also type a newline '\n', and the %c picks up the newline on the second pass.

If you allocate char command[2]; and use scanf("%1s", command), you should avoid most problems. The %s conversion specifier skips leading white space and the 1 limits the input to a single non-white-space character, which should help you out sufficiently.

Personally, I'd still use:

 char line[4096];

 while (fgets(line, sizeof(line), stdin) != 0)
 {
     char command[2];
     if (sscanf(line, "%1s", command) == 1)
         ...got a command...
     else
         ...failed...
 }

One reason for preferring this is that it eats the newline each time, but more importantly, if something goes wrong, you've got the whole line of information to use in the error reporting.



回答2:

    switch (command[0]) {
      case 'a':
    printf ("a\n");
    fflush(stdin);
        break;

      case 'h':
    printf ("help\n");
    fflush(stdin);
        break;

      default:
    printf ("default\n");
    fflush(stdin);
    }
  }

You Can Also Use Fflush to overcome from this problem



回答3:

If the user enter many command so there is a newline between 2 input commands. and you have to catch this newline in your fscanf by adding space at the beginning of the string format " %c" will allow to do that

fscanf (stdin," %c",command);

You can define command as char and not as pointer:

 char command;

and if you do, the fscanf should be changed to

fscanf (stdin,"%c",&command);

switch (command) {


回答4:

You should free your input buffer by using the function fflush(stdin);. After that, you will be able to take the next input.