fgets()函数不等待输入

3
我写了以下代码:
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]);
  }
}

我有一个输入文件,其中包含它所拥有的行数,然后是需要处理的那些行。所以我读取行数到变量N中,之后使用fgets获取该行并进行处理。
然而,fgets似乎在第一次调用时不会等待标准输入。我总是得到输出“-”,然后才等待输入。这意味着,在循环的第一次迭代中,fgets不会等待标准输入,只会像我的printf一样打印出两个由“-”分隔的空字符。
为什么会这样?如何让fgets每次都等待输入?我觉得这可能是一个线程问题。
3个回答

7
您可以在scanf()之后使用fflush()来刷新缓冲区,如下所示:
int N;
scanf("%d", &N);
fflush (stdin);
int i;
... (rest of code)...

所以换行符从stdin缓冲区中被擦除,下一个fgets()将停止请求输入。

4
尽管某些实现提供了 fflush(stdin) 函数,但它并不是标准 C 的一部分。除了 fflush(ostream) 之外的任何行为都是未定义的。请尽量避免使用它。 - asdf

5

正如geekosaur所说,你没有处理scanf留下的换行符。你可以修改scanf格式字符串以考虑它:

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

*[^\n] 表示忽略你的整数输入后面不是换行符的所有内容,但不要处理换行符(跳过它)。

测试程序输出:

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

2
但是这仍然会留下未读的换行符,这意味着它是接下来的 fgets() 读取的第一件事情,这通常不是预期的结果。 - geekosaur

3

这与线程无关。 scanf() 会准确地读取您要求的内容; 它会留下未读的所有其他内容,特别是数据后面的换行符。(你也没有处理用户可能没有输入你期望的内容的可能性。)

如果您想进行基于行的输入,请使用fgets()。不要使用scanf() 并希望系统能够神奇地理解您希望忽略未读内容。


我完全忘记了换行符。谢谢。 - darksky
由于某种原因,我创建了一个大小为1的char数组来存放int,因此:char Nc [1]fgets(Nc,1,stdin),但是再次遇到问题,fgets不等待读取任何内容。程序立即退出。 - darksky
@Nayefc:你仍然可以使用scanf。请查看我的答案。 - Evan Mulawski
@Nayefc:是的,程序只是存在,但我想你的意思是它只是退出 - Keith Thompson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接