fgets() not waiting for input

2019-01-20 16:36发布

问题:

I wrote the following code:

int N;
scanf("%d", &N);
int i;
for (i = 0; i < N; i++) {
  char line[LINE_MAX];
  if (fgets(line, LINE_MAX, stdin) != NULL) {
    // do stuff with line here
    printf("%c - %c\n", line[0], line[1]);
  }
}

I have an input file which has the number of lines it has, and then that number of lines followed which I want to process. So I read in the number of lines into N. After that, I use fgets to get the line to be able to process it.

However, fgets does not seem to wait for a stdin the first time. I always get output of -, and then it waits for input. Meaning, the first iteration of the loop, it is not waiting for standard input at fgets and just prints out two empty characters separated by - as my printf does.

Why is that? How can I get fgets to wait for input each time? I feel like it is a threading issue.

回答1:

As geekosaur said, you are not handling the newline left behind by scanf. You can modify your scanf format string to take it into account:

scanf("%d *[^\n]", &N);

*[^\n] says to ignore everything after your integer input that isn't a newline, but don't do anything with the newline (skip it).

Test program output:

emulawsk@cs:~/testing$ ./test2
3
13
1 - 3
26
2 - 6
59
5 - 9


回答2:

It has nothing to do with threading. scanf() reads exactly what you ask it to; it's leaving everything else unread, notably the newline following the data. (You also aren't dealing with the possibility that the user didn't type what you intended.)

If you want to do line oriented input, use fgets(). Don't use scanf() and hope the system can magically intuit that you want to ignore what you didn't read.



回答3:

You can place a call to fflush() just after the scanf() like this:

int N;
scanf("%d", &N);
fflush (stdin);
int i;
... (rest of code)...

So the newline character ges erased from the stdin buffer and the next fgets() will stop to ask for input.



标签: c fgets