2012-09-16 145 views
41

即使是输出流,fflush()也不应该用于冲洗缓冲区?C中的冲洗缓冲区

它有什么用?一般来说,我们如何冲洗一个缓冲区?

+0

只需注意fflush输出流只明确定义,它不能在输入流中:那将是不确定的行为。 – Lundin

+0

@Lundin可以使用它来刷新输出流吗? – saadtaame

+2

@saadtaame是的,这正是'fflush()'的用处。 – Mysticial

回答

75

我从来没有听说过不冲洗输出缓冲区,我会有兴趣听到你的来源。法拉盛输出缓冲器:

printf("Buffered, will be flushed"); 
fflush(stdout); // Prints to screen or whatever your standard out is 

fprintf(fd, "Buffered, will be flushed"); 
fflush(fd); //Prints to a file 

可以是一个非常有用的技术。你为什么要刷新一个输出缓冲区?通常当我这样做的时候,这是因为代码崩溃了,我试图调试一些东西。标准缓冲区不会在您每次打电话时打印printf(),它会一直等到它满了然后立即转储一堆。所以如果你想在碰撞发生之前检查你是否正在调用一个函数,那么printf会有帮助,比如“got here!”,有时在崩溃发生之前缓冲区没有被刷新,你可以不知道你真的得到了多少。

另一次有用的是多进程或多线程代码。同样,缓冲区并不总是在对printf()的调用时刷新,所以如果你想知道多个进程的执行顺序,你应该在每次打印之后刷新缓冲区。

我养成这样做的习惯,它在调试时节省了很多头痛。我认为唯一的缺点是printf()是一个昂贵的操作(这就是为什么它不会默认刷新缓冲区)。


至于冲洗输入缓冲器(stdin),你不应该这样做。冲洗stdin是根据C11标准未定义的行为§7.21.5.2第2部分:

如果流点到输出流... fflush函数导致该流的任何未写入的数据...将被写入到文件;否则,行为是不确定的。

在某些系统,Linux是一个你可以在手册页看到fflush(),有一个定义的行为,但它是依赖于系统,使您的代码将不能移植。现在,如果你在输入缓冲区很担心垃圾“卡壳”

您可以使用上fpurge()。 见here更多关于fflush()fpurge()

+1

谢谢! stdin(或任何其他缓冲区)如何? – saadtaame

+0

看我的编辑(最后一段),也许这将有所帮助。 – Mike

+0

使用'fflush(stdin)'绝对适用于VS08/10。不管它是“明确的”还是不是我都不知道。它可能是VS中的一个“修复”,因为我相当确定它不适用于Linux。 – ChiefTwoPencils