C语言 fflush(stdin) 在 C 编程中有什么作用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22901901/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What does fflush(stdin) do in C programing?
提问by C graphics
I am very new to C programming and I am trying to understand how fflush(stdin)really works.
我对 C 编程很陌生,我试图了解fflush(stdin)真正的工作原理。
In the following example does fflush(stdin)clears all the buffer or it clears whatever entered after the third item? What I mean is user enters account number, space, name, space, balance. Is that true that from this point on, whatever the user enters will be flushed with fflush(stdin)? and stdinwon't be empty.
在下面的示例中是fflush(stdin)清除所有缓冲区还是清除第三项之后输入的任何内容?我的意思是用户输入帐号、空格、姓名、空格、余额。从现在开始,用户输入的任何内容都将被刷新,这是真的fflush(stdin)吗?并且stdin不会为空。
Why do I say that is because it enters into a while loop and starts writing to the text file.
为什么这么说是因为它进入了一个while循环并开始写入文本文件。
My second question is whether Ctrl-Zwill tell the OS to stop asking the user for entering input?
我的第二个问题是是否Ctrl-Z会告诉操作系统停止要求用户输入?
printf( "Enter the account name and balance. (separated by spaces)\n" );
printf( "Enter EOF to end input. (Ctrl-Z)\n" );
printf( "? " );
scanf( "%d%s%lf", &account, name, &balance );
fflush(stdin);
// write account, name and balance into file with fprintf
while ( !feof( stdin ) )
{
//fflush(stdin);
fprintf( cfPtr, "%d %s %.2f\n", account, name, balance );
printf( "? " );
scanf( "%d%s%lf", &account, name, &balance );
}
fclose( cfPtr );
回答by Emmet
The answer to this is that fflush(stream)is only formally defined for output streams, so fflush(stdout)is OK, but fflush(stdin)is not.
对此的答案是,fflush(stream)它只是为输出流正式定义,所以fflush(stdout)可以,但fflush(stdin)不是。
The purpose of fflush(stream)is to make the operating system flush any buffers to the underlying file. For an example of a legitimate use, students often have problems like “my prompt doesn't appear!” if they do something like:
的目的fflush(stream)是让操作系统将任何缓冲区刷新到底层文件。举一个合法使用的例子,学生经常会遇到“我的提示没有出现!”之类的问题。如果他们做这样的事情:
printf("Enter a number: ");
However, they find that this works just fine:
但是,他们发现这很好用:
printf("Enter a number:\n");
Of course, they don't want a newline after their prompt, so they have a bit of a problem.
当然,他们不希望在他们的提示之后换行,所以他们有一点问题。
The reason for this is that the output to stdoutis buffered by the OS and the default behavior is (often) only to actually write the output to the terminal when a newline is encountered. Adding an fflush(stdout)after the printf()solves the problem:
这样做的原因是输出 tostdout由操作系统缓冲,并且默认行为(通常)仅在遇到换行符时实际将输出写入终端。fflush(stdout)在printf()解决问题后添加:
printf("Enter a number: ");
fflush(stdout);
Now, working by analogy, people often think that fflush(stdin)should discard any unused input, but if you think about it a little bit that doesn't make much sense. What does it mean to “flush” an input buffer? Where is it “flushed” to? If you flush an output buffer, the output is sent to the underlying file or the terminal, where it would eventually wind up anyway, but where would input“eventually end up anyway”? There's no way of knowing! What should the behavior be if the input stream data comes from a file or a pipe or a socket? It isn't at allclear for input streams what the behavior of fflush()should be, but it's very clear for output streams in all cases. Hence, fflush()is only defined for output streams.
现在,以此类推,人们通常认为fflush(stdin)应该丢弃任何未使用的输入,但是如果您稍微考虑一下,这没有多大意义。“刷新”输入缓冲区是什么意思?它在哪里“刷新”来?如果刷新输出缓冲区,输出将发送到底层文件或终端,无论如何它最终都会在那里结束,但是输入“最终还是会结束”?没有办法知道!如果输入流数据来自文件、管道或套接字,行为应该是什么?这不是在所有明确的输入流的行为,什么fflush()是应该的,但在所有情况下,输出流是非常明确的。因此,fflush()仅为输出流定义。
The reason why the erroneous use of fflush(stdin)became commonplace is that, many years ago, a few operating systems didimplement a scheme where it worked as many people expected, discarding unused input. Microsoft DOSis a good example. Surprisingly, modern versions of Linuxalso implement fflush()for input streams.
错误使用fflush(stdin)变得司空见惯的原因是,多年前,一些操作系统确实实施了一种方案,它可以按许多人的预期工作,丢弃未使用的输入。Microsoft DOS就是一个很好的例子。令人惊讶的是,现代版本的Linux也实现fflush()了输入流。
The right thing to do with “extra” unwanted terminal input is simply to read it and do nothing with it. This is almost as easy as calling fflush(stdin), works everywhere, and doesn't rely on formally undefined behavior.
处理“额外”不需要的终端输入的正确做法是简单地阅读它而不用它做任何事情。这几乎和调用一样简单fflush(stdin),适用于任何地方,并且不依赖于形式上未定义的行为。
The Cstandard says:
该Ç标准说:
If stream points to an output streamor an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined.
如果stream 指向一个输出流或一个更新流,其中最近的操作没有输入,则 fflush 函数会导致该流的任何未写入的数据被传递到主机环境以写入文件;否则,行为是 undefined。
POSIX says(also explicitly defers to Cstandard):
POSIX 说(也明确遵循C标准):
If stream points to an output streamor an update stream in which the most recent operation was not input, fflush() shall cause any unwritten data for that stream to be written to the file, ...
如果流指向没有输入最近操作的输出流或更新流,则 fflush() 将导致该流的任何未写入数据写入文件,...
But the Linux manpagesays:
但是Linux 联机帮助页说:
For output streams, fflush() forces a write of all user-space buffered data for the given output or update stream via the stream's underlying write function. For input streams, fflush() discards any buffered data that has been fetched from the underlying file, but has not been consumed by the application. The open status of the stream is unaffected.
对于输出流, fflush() 通过流的底层写入函数强制写入给定输出或更新流的所有用户空间缓冲数据。对于输入流, fflush() 丢弃已从底层文件中获取但尚未被应用程序使用的任何缓冲数据。流的打开状态不受影响。
回答by chrk
fflush(stdin)invokes undefined behaviour.
fflush(stdin)调用未定义的行为。
fflush()is defined only for output streams. You should not do it.
fflush()仅针对输出流定义。你不应该这样做。
On Unix, Ctrl-Z sends a TSTP signal (SIGTSTP) which by default causes the process to suspend execution.
在 Unix 上,Ctrl-Z 发送 TSTP 信号 (SIGTSTP),默认情况下会导致进程暂停执行。

