-1

Linux 手册建议fflush不要使用该功能。

所以,我发现它while( getchar() != '\n'的作用与fflush(stdin).

例如)

我的试用代码:

#include <stdio.h>

void main(void)
{
    char input[100] = {};
    printf("abcd");
    while(1);
}

如果我在 Linux(Ubuntu)中执行上面的代码,结果什么都没有。因为\n不在字符串中。stdout所以,我必须通过清空缓冲区来打印它们。

奇怪的现象是,当我使用getc(stdout)或时,结果打印得很好getc(stdin)

#include <stdio.h>

void main(void)
{
    char input[100] = {};
    printf("abcd");
    getc(stdout); // or getc(stdin); both working well.
    while(1);
}

我不知道为什么两者都做得很好。我希望这只能getc(stdout)很好地工作,因为我将stdin其视为键盘缓冲区和stdout监视器缓冲区。

4

2 回答 2

2

Read carefully the documentation of fflush(3) (for input streams, it has a documented effect only on seekable files, not on stdin when it is a terminal). AFAIK, fflush(stdin) is undefined behavior (when stdin is a terminal), and certainly does not do the same as while( getchar() != '\n'; you should call fflush on some output FILE* handle or on NULL

Your first example would work as expected if you add a fflush(NULL); or a fflush(stdout); call before the while(1); busy waiting loop (actually, you should call sleep(3) inside that loop, at least to avoid heating your processor).

Notice that stdin can (on Linux) be a tty(4), or a file or a pipe(7) (e.g. with shell redirection or pipelines), etc....

Terminals, that is ttys, are -mostly for historical reasons- quite complex things. Read the tty demystified page. In many situations, you have some double buffering: the kernel is buffering the tty thru its line discipline, and the C standard library is buffering the stdin. See setvbuf(3). Of course a tty is not the keyboard (but some abstraction above it). Very likely, on your Linux desktop, the physical keyboard is only read by the X11 server.

If you care about interactive input from a terminal, consider using some library like ncurses or readline

Read Advanced Linux Programming

And the behavior of your second case can be explained by the fact that some C standard libraries are implicitly flushing stdout before reading from stdin, but AFAIK this is not guaranteed, and you certainly should call explicitly fflush (in particular, for readability reasons) when needed!

Read the documentation of getc(3), it can fail (and probably would fail with stdout).

于 2015-11-30T05:36:25.477 回答
-1

You can use setbuf(stdout, NULL); function call to get same effect as fflush(stdin).

于 2015-11-30T05:36:03.873 回答