linux下如何清空(刷新)stdin缓冲区?注意是清空(刷新),而不是关闭.

系统安装、升级讨论
版面规则
我们都知道新人的确很菜,也喜欢抱怨,并且带有浓厚的Windows习惯,但既然在这里询问,我们就应该有责任帮助他们解决问题,而不是直接泼冷水、简单的否定或发表对解决问题没有任何帮助的帖子。乐于分享,以人为本,这正是Ubuntu的精神所在。
科学之子
帖子: 2284
注册时间: 2013-05-26 6:58
系统: Debian 9

linux下如何清空(刷新)stdin缓冲区?注意是清空(刷新),而不是关闭.

#1

帖子 科学之子 » 2014-05-03 16:50

linux下如何清空(刷新)stdin缓冲区?注意是清空(刷新),而不是关闭.

代码: 全选

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    putchar(getchar());
    fflush(stdout);
    fflush(stdin);
    putchar(getchar());
    fflush(stdout);
    system("sleep 4");
    return 0;
}
Mon May 5 15:46:02 CST 2014补充:
其实为了避免下次输入时的数据收到上次输入的干扰.
现在看来,只能通过回车来判断结束了.
上次由 科学之子 在 2014-05-05 15:47,总共编辑 6 次。
头像
astolia
论坛版主
帖子: 6703
注册时间: 2008-09-18 13:11

Re: linux下如何刷新stdout缓冲区?注意是刷新,而不是关闭.

#2

帖子 astolia » 2014-05-03 22:50

不知道你所说的“刷新”是什么意思
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: linux下如何刷新stdout缓冲区?注意是刷新,而不是关闭.

#3

帖子 eexpress » 2014-05-04 8:51

估计就是要输入clear。
如果是脚本或者软件控制,并清空历史,是输入一个esc \b还是\c的序列。一下子找不到脚本了。
● 鸣学
头像
comp_286
帖子: 178
注册时间: 2006-03-12 14:17

Re: linux下如何刷新stdout缓冲区?注意是刷新,而不是关闭.

#4

帖子 comp_286 » 2014-05-04 9:26

我觉得他说的是C语言编程里面的“缓冲区刷新”。fflush(stdout);
科学之子
帖子: 2284
注册时间: 2013-05-26 6:58
系统: Debian 9

Re: linux下如何刷新stdout缓冲区?注意是刷新,而不是关闭.

#5

帖子 科学之子 » 2014-05-04 15:50

astolia 写了:不知道你所说的“刷新”是什么意思
就是想有没有库函数可以像windows下的fflush(stdout)那样.
科学之子
帖子: 2284
注册时间: 2013-05-26 6:58
系统: Debian 9

Re: linux下如何刷新stdout缓冲区?注意是刷新,而不是关闭.

#6

帖子 科学之子 » 2014-05-04 15:51

eexpress 写了:估计就是要输入clear。
如果是脚本或者软件控制,并清空历史,是输入一个esc \b还是\c的序列。一下子找不到脚本了。
不是这个意思,刷新的意思是让stdout的缓冲区立即输出到屏幕.
就像fflush(stdout)那样(linux下没法这样)
科学之子
帖子: 2284
注册时间: 2013-05-26 6:58
系统: Debian 9

Re: linux下如何刷新stdout缓冲区?注意是刷新,而不是关闭.

#7

帖子 科学之子 » 2014-05-04 15:52

comp_286 写了:我觉得他说的是C语言编程里面的“缓冲区刷新”。fflush(stdout);
就是这个意思.
有办法吗?
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: linux下如何刷新stdout缓冲区?注意是刷新,而不是关闭.

#8

帖子 eexpress » 2014-05-04 16:09

▶ man fflush
不是一样嘛。stdout只是一个句柄而已。
● 鸣学
头像
cjxgm
帖子: 1952
注册时间: 2010-04-23 20:40
系统: Arch Linux
来自: 浙江·杭州
联系:

Re: linux下如何刷新stdout缓冲区?注意是刷新,而不是关闭.

#9

帖子 cjxgm » 2014-05-04 19:18

#include <stdio.h>
fflush(stdout);

LZ没有放出代码,也没有放出编译错误信息,不知道不能编译的具体原因
但是据某猜测,很可能是 include 没写/没写对,因为我身边的 windows 程序员从来没写对过 include(而且 windows 里可以编译通过)
Clanjor Prods. | Develop for Developers. (C++, Lua) | 作曲编曲 | 实时渲染引擎
科学之子
帖子: 2284
注册时间: 2013-05-26 6:58
系统: Debian 9

Re: linux下如何刷新stdout缓冲区?注意是刷新,而不是关闭.

#10

帖子 科学之子 » 2014-05-04 23:20

eexpress 写了:▶ man fflush
不是一样嘛。stdout只是一个句柄而已。
原来如此(网上各种说fflush不能在linux下用,所以就以为linux没fflush,原来只是实现不一样)
但fflush(stdin)就不行了吧?
连续输入的字符还是会被读取.不会因为刷新就被清空.

代码: 全选

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    putchar(getchar());
    fflush(stdout);
    fflush(stdin);
    putchar(getchar());
    fflush(stdout);
    system("sleep 4");
    return 0;
}
上次由 科学之子 在 2014-05-04 23:27,总共编辑 1 次。
科学之子
帖子: 2284
注册时间: 2013-05-26 6:58
系统: Debian 9

Re: linux下如何刷新stdout缓冲区?注意是刷新,而不是关闭.

#11

帖子 科学之子 » 2014-05-04 23:24

cjxgm 写了:#include <stdio.h>
fflush(stdout);

LZ没有放出代码,也没有放出编译错误信息,不知道不能编译的具体原因
但是据某猜测,很可能是 include 没写/没写对,因为我身边的 windows 程序员从来没写对过 include(而且 windows 里可以编译通过)
呃...网上各种说fflush在linux下不行,我就不知道为什么,理解成没有了.
好吧,有,而且对stdout有效果.
但stdin呢?
连续输入的字符还是会被读取.不会因为刷新就被清空.

代码: 全选

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    putchar(getchar());
    fflush(stdout);
    fflush(stdin);
    putchar(getchar());
    fflush(stdout);
    system("sleep 4");
    return 0;
}
科学之子
帖子: 2284
注册时间: 2013-05-26 6:58
系统: Debian 9

Re: linux下如何刷新stdout缓冲区?注意是刷新,而不是关闭.

#12

帖子 科学之子 » 2014-05-04 23:37

astolia 写了:不知道你所说的“刷新”是什么意思
现在明确了,刷新的意思是清空输入缓冲区.
头像
astolia
论坛版主
帖子: 6703
注册时间: 2008-09-18 13:11

Re: linux下如何清空(刷新)stdin缓冲区?注意是清空(刷新),而不是关闭.

#13

帖子 astolia » 2014-05-05 0:33

首先,fflush在C/C++/POSIX标准中只定义了处理输出流的行为,对于像stdin这种输入流,这是未定义行为undefined behavior,随便C/C++库怎么去实现都不算错。即使某个C/C++库对fflush(stdin)的处理是删除掉你硬盘上所有文件都没有错。所以你根本不要指望任何未定义行为能在不同平台下有相同的表现。

再来看看linux对fflush(stdin)的说法

代码: 全选

man 3 fflush
For input streams, fflush() discards any buffered data that has been
fetched from the underlying file, but has not been consumed by the application.
说的是如果对fflush传入一个输入流,会清除已经从输入流中取出但还没有交给程序的数据

注意红字部分。fflush处理的是已经从输入流中取出的数据,而不是输入流中剩余的数据。而且这数据还不能交给程序,也就是说,对于getchar这种函数,只有其还未返回时,stdin的输入缓冲区才可能有数据,此时调用fflush才会有用

代码: 全选

man 3 stdin
Note that in case stdin is
associated with a terminal, there may also be input buffering in the
terminal driver, entirely unrelated to stdio buffering. (Indeed, nor‐
mally terminal input is line buffered in the kernel.)
和上面连起来看就更明白了,终端驱动中接收你输入文本的缓冲区就相当于是输入流,和stdin的缓冲区是两回事

而在glibc的文档中,关于fflush的说明如下
http://www.gnu.org/software/libc/manual ... ffers.html
This function causes any buffered output on stream to be delivered to the file. If stream is a null pointer, then fflush causes buffered output on all open output streams to be flushed.
连输入流都没提到。说明glibc实现中的fflush要么对输入流什么都没干,要么干了些对外部完全没有影响的事

要想实现你所希望的效果,可以用非标准的fpurge()。glibc中的近似实现是__fpurge()。自己去

代码: 全选

man 3 fpurge
头像
cjxgm
帖子: 1952
注册时间: 2010-04-23 20:40
系统: Arch Linux
来自: 浙江·杭州
联系:

Re: linux下如何清空(刷新)stdin缓冲区?注意是清空(刷新),而不是关闭.

#14

帖子 cjxgm » 2014-05-05 12:31

代码: 全选

NOTES
       Usually it is a mistake to want to discard input buffers.
LZ 为什么要清stdin呢?
Clanjor Prods. | Develop for Developers. (C++, Lua) | 作曲编曲 | 实时渲染引擎
科学之子
帖子: 2284
注册时间: 2013-05-26 6:58
系统: Debian 9

Re: linux下如何清空(刷新)stdin缓冲区?注意是清空(刷新),而不是关闭.

#15

帖子 科学之子 » 2014-05-05 16:03

cjxgm 写了:

代码: 全选

NOTES
       Usually it is a mistake to want to discard input buffers.
LZ 为什么要清stdin呢?
为了避免不同输入之间的干扰.
貌似可以通过回车来判断输入结束.
只是以前windows时习惯了fflush,感觉比较省事.
回复