在C语言中使用fflush(stdin)

    fflush() 通常仅用于输出流。它的目的是清除(或刷新)输出buffer,并将缓冲的数据移动到控制台(在stdout的情况下)或磁盘(在文件输出流的情况下)。下面是它的语法。

fflush(FILE *ostream);
ostream 指向一个输出流或一个更新流,其中最近的操作不是输入。fflush函数会导致将该流的任何未写入数据传递到主机环境,并写入该文件;否则,行为未定义。
我们可以将它用于像 stdin 这样的输入流吗?

    根据 C 标准,使用 fflush(stdin) 是未定义的行为。然而,一些编译器如 Microsoft Visual Studio 允许它。在这些编译器中如何使用它? 在获取带空格的输入字符串时,缓冲区不会为下一个输入清除,而是将前一个视为相同输入。为了解决这个问题,使用 fflush(stdin) 清除流/缓冲区。

// C program to illustrate situation
// where flush(stdin) is required only
// in certain compilers.
#include <stdio.h>
#include <stdlib.h>
int main()
{
	char str[20];
	int i;
	for (i=0; i<2; i++)
	{
		scanf("%[^\n]s", str);
		printf("%s\n", str);
		// fflush(stdin);
	}
	return 0;
}

    输入:

geeks   
geeksforgeeks

    输出:

geeks 
geeks

    上面的代码只接受一个输入,并为第二个输入提供相同的结果。原因是因为字符串已经存储在缓冲区中,即流尚未清除,因为它希望字符串带有空格或新行。因此,使用 fflush(stdin) 来处理这种情况。

// C program to illustrate flush(stdin)
// This program works as expected only
// in certain compilers like Microsoft
// visual studio.
#include <stdio.h>
#include <stdlib.h>
int main()
{
	char str[20];
	int i;
	for (i = 0; i<2; i++)
	{
		scanf("%[^\n]s", str);
		printf("%s\n", str);

		// used to clear the buffer
		// and accept the next string
		fflush(stdin);
	}
	return 0;
}

    输入:

geeks
geeksforgeeks

    输出:

geeks 
geeksforgeeks

    说明:
    scanf("%[^\n]s", str); 等价于 gets(str);
    %[^\n] 可读取带有空格的字符串,以换行符结尾。具体可参考 scanf(“%[^\n]s”, str) Vs gets(str)

使用fflush(stdin)好吗?

    虽然在“scanf()”语句之后使用“fflush(stdin)”也会清除某些编译器中的输入缓冲区,但不建议使用它,因为这是语言标准未定义的行为。在C和C++中,我们有不同的方法来清除在这个帖子中讨论的缓冲区。

参考文档

[1]Sahil Chhabra.Use of fflush(stdin) in C[EB/OL].https://www.geeksforgeeks.org/use-fflushstdin-c/,2018-12-13.

上一篇:python的Popen多行交互


下一篇:freopen函数的使用以及freopen与fopen的区别