简体   繁体   English

C:清除stdin输入缓冲区无法正常使用fgets()

[英]C: Clearing stdin input buffer not working as expected with fgets()

I am using the following method clear the input buffer: 我正在使用以下方法清除输入缓冲区:

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

This works fine if I read from stdin using scanf(): 如果我使用scanf()从stdin中读取,则此方法可以正常工作:

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

However, if I use fgets() instead, as in the following code: 但是,如果我改用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;

Since fgets() reads in the '\\n' character I found the need to allocate a buffer one char larger and trim the string back one character. 由于fgets()读入'\\ n'字符,因此我发现需要为缓冲区分配一个大字符,并将字符串修剪回一个字符。 This works fine but there is a problem with the dump_line function. 这可以正常工作,但dump_line函数存在问题。 When using the scanf() version, it works as expected since there will always be a '\\n' left in the input buffer due to the use of [^\\n]. 使用scanf()版本时,它可以按预期工作,因为由于使用[^ \\ n],在输入缓冲区中总会留有'\\ n'。 So even if that is the only char left in the buffer, in dump_line() the fgetc() reads the char and since it is a '\\n' the while loop is broken. 因此,即使这是缓冲区中剩下的唯一字符,在dump_line()中,fgetc()也会读取该字符,由于它是一个'\\ n',因此while循环中断了。

In the fgets() version, the '\\n' is read in if it will fit in the string buffer, leaving stdin empty. 在fgets()版本中,如果将'\\ n'放入字符串缓冲区中,则将其读入,而stdin为空。 This is causing the program to wait on the fgetc(), requiring the user to hit the enter key to progress any further, which is obviously not what I am after. 这导致程序在fgetc()上等待,要求用户按Enter键以进一步进行操作,这显然不是我所追求的。 On the other hand, if the user enters a string too long for the buffer, the dump_line() is working fine! 另一方面,如果用户输入的字符串对于缓冲区而言太长,则dump_line()可以正常工作!

Im guessing the problem is something to do with EOF, but I cannot seem to get this to work as intended! 我想这个问题与EOF有关,但我似乎无法使它按预期工作! Any help would greatly be appreciated. 任何帮助将不胜感激。

If it is any help the platform I am working on is Mac OSX, just in case this is some kind of platform-specific quirk. 如果对我正在使用的平台是Mac OSX有帮助,以防万一这是某种特定于平台的怪癖。

Check whether you need to clear the buffer, 检查是否需要清除缓冲区,

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);
}

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM