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

tom*_*990 1 c macos stdin fgets eof

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

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

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

char string[51];
...
scanf("%50[^\n]", string);
dump_line(stdin);
Run Code Online (Sandbox Code Playgroud)

但是,如果我改为使用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;
Run Code Online (Sandbox Code Playgroud)

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

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

我猜这个问题与EOF有关,但我似乎无法让它按预期工作!任何帮助将不胜感激.

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

Dan*_*her 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);
}
Run Code Online (Sandbox Code Playgroud)