fflush(stdin) 在 C 编程中有什么作用? [英] What does fflush(stdin) do in C programing?

查看:16
本文介绍了fflush(stdin) 在 C 编程中有什么作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 C 编程的新手,我正在尝试了解 fflush(stdin) 的真正工作原理.

I am very new to C programming and I am trying to understand how fflush(stdin) really works.

在以下示例中,fflush(stdin) 是清除所有缓冲区还是清除第三项之后输入的任何内容?我的意思是用户输入帐号、空格、姓名、空格、余额.从现在开始,用户输入的任何内容都会被 fflush(stdin) 刷新,这是真的吗?并且 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 stdin won't be empty.

为什么这么说是因为它进入了一个while循环并开始写入文本文件.

Why do I say that is because it enters into a while loop and starts writing to the text file.

我的第二个问题是 Ctrl-Z 是否会告诉操作系统停止要求用户输入输入?

My second question is whether Ctrl-Z will tell the OS to stop asking the user for entering input?

printf( "Enter the account name and balance. (separated by spaces)
" );
  printf( "Enter EOF to end input. (Ctrl-Z)
" );
  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
", account, name, balance );
     printf( "? " );
     scanf( "%d%s%lf", &account, name, &balance );
  }

  fclose( cfPtr );

推荐答案

这个问题的答案是 fflush(stream) 只是正式定义了输出流,所以 fflush(stdout) 可以,但 fflush(stdin) 不行.

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) 的目的是让操作系统将所有缓冲区刷新到底层文件.以合法使用为例,学生经常会遇到我的提示没有出现!"之类的问题.如果他们这样做:

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:

printf("Enter a number: ");

但是,他们发现这很好用:

However, they find that this works just fine:

printf("Enter a number:
");

当然,他们不想在提示后换行,所以他们有点问题.

Of course, they don't want a newline after their prompt, so they have a bit of a problem.

这样做的原因是 stdout 的输出由操作系统缓冲,并且默认行为(通常)仅在遇到换行符时实际将输出写入终端.在 printf() 后添加 fflush(stdout) 即可解决问题:

The reason for this is that the output to stdout is 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:

printf("Enter a number: ");
fflush(stdout);

现在,打个比方,人们通常认为 fflush(stdin) 应该丢弃任何未使用的输入,但如果您稍微考虑一下,这并没有多大意义.刷新"输入缓冲区是什么意思?冲"到哪里去了?如果刷新输出缓冲区,则输出将发送到底层文件或终端,无论如何它最终都会结束,但是 input 最终还是会结束"?没有办法知道!如果输入流数据来自文件、管道或套接字,应该有什么行为?根本不清楚输入流的 fflush() 的行为应该是什么,但在所有情况下对于输出流来说都非常清楚.因此,fflush() 只为输出流定义.

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 all clear 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) 的错误使用变得司空见惯的原因是,许多年前,一些操作系统确实实施了一种方案,它可以在许多情况下工作人们期望,丢弃未使用的输入.Microsoft DOS 就是一个很好的例子.令人惊讶的是,现代版本的 Linux 还为输入流实现了​​ fflush().

The reason why the erroneous use of fflush(stdin) became commonplace is that, many years ago, a few operating systems did implement a scheme where it worked as many people expected, discarding unused input. Microsoft DOS is a good example. Surprisingly, modern versions of Linux also implement fflush() for input streams.

处理额外"不需要的终端输入的正确做法是简单地读取它而不用它做任何事情.这几乎和调用 fflush(stdin) 一样简单,可以在任何地方使用,并且不依赖于正式未定义的行为.

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.

C 标准说:

如果 stream 指向输出流或更新流,其中没有输入最近的操作,则 fflush 函数会将该流的任何未写入数据传递到主机环境写入文件;否则,行为未定义.

If stream points to an output stream or 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.

POSIX 说(也明确地遵循 C 标准):

POSIX says (also explicitly defers to C standard):

如果流指向输出流或更新流,其中没有输入最近的操作,fflush() 将导致该流的任何未写入数据写入文件,...

If stream points to an output stream or 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, ...

但是 Linux 手册页 说:

对于输出流,fflush() 通过流的底层写入函数强制写入给定输出或更新流的所有用户空间缓冲数据.对于输入流,fflush() 会丢弃任何已从基础文件中提取但尚未被应用程序使用的缓冲数据.流的打开状态不受影响.

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(stdin) 在 C 编程中有什么作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆