简体   繁体   中英

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():

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

However, if I use fgets() instead, as in the following code:

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. This works fine but there is a problem with the dump_line function. 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]. 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.

In the fgets() version, the '\\n' is read in if it will fit in the string buffer, leaving stdin empty. 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. On the other hand, if the user enters a string too long for the buffer, the dump_line() is working fine!

Im guessing the problem is something to do with EOF, but I cannot seem to get this to work as intended! 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.

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将换行符放回流中。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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