C:使用fgets()清除stdin输入缓冲区不能正常工作

时间:2013-01-17 16:51:42

标签: c macos stdin eof fgets

我使用以下方法清除输入缓冲区:

void dump_line(FILE *fp) {
    int ch;    
    while ( (ch = fgetc(fp)) != EOF && ch != '\n');
}

如果我使用scanf()从stdin读取,这可以正常工作:

char string[51];
...
scanf("%50[^\n]", string);
dump_line(stdin);

但是,如果我改为使用fgets(),如下面的代码所示:

char string[52];
...
fgets(string, 52, stdin);
dump_line(stdin);

// Since fgets() reads in the '\n', trim the end of the string:
string[strlen(string)-1] = 0;

由于fgets()读入'\ n'字符,我发现需要分配一个较大的char缓冲区并将字符串修剪回一个字符。这工作正常,但dump_line函数存在问题。当使用scanf()版本时,它按预期工作,因为由于使用[^ \ n],输入缓冲区中将始终存在'\ n'。因此,即使这是缓冲区中剩下的唯一字符,在dump_line()中,fgetc()读取char,因为它是'\ n',所以while循环被破坏。

在fgets()版本中,如果它适合字符串缓冲区,则读入'\ n',将stdin留空。这导致程序在fgetc()上等待,要求用户按Enter键进一步前进,这显然不是我所追求的。另一方面,如果用户为缓冲区输入的字符串太长,dump_line()工作正常!

我猜这个问题与EOF有关,但我似乎无法让它按预期工作!非常感谢任何帮助。

如果有任何帮助,我正在使用的平台是Mac OSX,以防万一这是某种特定于平台的怪癖。

2 个答案:

答案 0 :(得分:5)

检查是否需要清除缓冲区,

fgets(string, 52, stdin);
size_t len = strlen(string);
if (string[len-1] == '\n') {
    // read in whole line, no need to clear buffer
    string[len-1] = 0;
} else {
    // junk left in buffer, clear it
    dump_line(stdin);
}

答案 1 :(得分:1)

您可以使用ungetc将换行符放回流中。