这个问题已经有了答案:
Using fflush(stdin)
4个答案
我对c编程很陌生,我正试图了解fflush(stdin)是如何工作的。
在下面的示例中,fflush(stdin)是清除所有缓冲区还是清除在第三项之后输入的内容?我的意思是用户输入帐号,空格,名字,空格,余额。从现在开始,用户输入的任何内容都将用fflush(stdin)刷新,这是真的吗?stdin不会是空的。
我为什么这么说是因为它进入一个while循环并开始写入文本文件。
我的第二个问题是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 );

最佳答案

答案是fflush(stream)只是为输出流定义的,所以fflush(stdout)是可以的,但fflush(stdin)不是。
fflush(stream)的目的是使操作系统将任何缓冲区刷新到基础文件。作为一个合法使用的例子,学生们经常会遇到这样的问题:“我的提示没有出现!“如果他们这样做:

printf("Enter a number: ");

然而,他们发现这样做很好:
printf("Enter a number:\n");

当然,他们在提示后不需要换行,所以他们有点问题。
其原因是stdout的输出由操作系统缓冲,默认行为(通常)仅在遇到换行符时才实际将输出写入终端。在fflush(stdout)之后添加printf()可以解决问题:
printf("Enter a number: ");
fflush(stdout);

现在,通过类比,人们通常认为fflush(stdin)应该丢弃任何未使用的输入,但是如果你稍微考虑一下,那就没有多大意义了。“刷新”输入缓冲区意味着什么?它“冲”到哪里去了?如果刷新输出缓冲区,则将输出发送到底层文件或终端,在那里它最终会结束,但在哪里输入“最终会结束”?没办法知道!如果输入流数据来自文件、管道或套接字,那么应该如何处理?对于输入流来说,fflush()的行为应该是什么并不清楚,但是对于输出流来说,在所有情况下都非常清楚。因此,fflush()仅为输出流定义。
错误使用fflush(stdin)变得司空见惯的原因是,许多年前,一些操作系统确实实现了一种方案,在这种方案中,它可以像许多人所期望的那样工作,丢弃未使用的输入。微软dos就是一个很好的例子。令人惊讶的是,现代版本的linux还为输入流实现了fflush()
正确的做法是“额外的”不需要的终端输入只是读取它而不做任何事情。这几乎和调用fflush(stdin)一样简单,可以在任何地方工作,并且不依赖于形式上未定义的行为。
C标准规定:
如果流指向没有输入最新操作的输出流或更新流,则fflush函数会导致将该流的任何未写入数据传递到主机环境并写入文件;否则,行为未定义。
POSIX says(也明确遵从c标准):
如果流指向没有输入最新操作的输出流或更新流,fflush()将导致该流的任何未写入数据写入文件,…
但是Linux manpage说:
对于输出流,fflush()通过流的底层写函数强制写入给定输出或更新流的所有用户空间缓冲数据。对于输入流,fflush()丢弃已从基础文件中提取但尚未被应用程序使用的任何缓冲数据。流的打开状态不受影响。

关于c - fflush(stdin)在C编程中做什么? ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22901901/

10-11 00:13