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用作监视器缓冲区。

最佳答案

仔细阅读fflush(3)的文档(对于输入流,它仅对可搜索的文件有效,而对作为终端的stdin无效)。 AFAIK,fflush(stdin)是未定义的行为(当stdin是终端时),当然与
while( getchar() != '\n';您应该在某些输出fflush句柄或FILE*上调用NULL

如果在fflush(NULL);繁忙等待循环之前添加fflush(stdout);while(1);调用,则第一个示例将按预期工作(实际上,您应该在该循环内调用sleep(3),至少是为了避免加热处理器)。

请注意,stdin(在Linux上)可以是tty(4),文件或pipe(7)(例如具有shell重定向或管道)等等。

终端(即ttys)(主要是出于历史原因)非常复杂。阅读tty demystified页。在许多情况下,您有一些双重缓冲:内核通过tty的line discipline缓冲tty,而C standard library的stdin缓冲。请参见setvbuf(3)。当然,tty不是键盘(而是键盘上方的某种抽象)。在您的Linux桌面上,很可能只有X11服务器才能读取物理键盘。

如果您关心来自终端的交互式输入,请考虑使用某些库,例如ncursesreadline

阅读Advanced Linux Programming

第二种情况的行为可以通过以下事实来解释:某些C标准库在从stdin读取之前隐式刷新了stdout,但是AFAIK不能保证,您当然应该显式调用fflush(尤其是出于可读性原因) ) 需要的时候!

阅读getc(3)的文档,它可能会失败(并且可能因stdout而失败)。

关于c - 与Linux中的fflush函数有什么相同?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33991989/

10-11 20:13