清除 C/C++ 中的输入缓冲区

323 阅读2分钟

「这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战

什么是缓冲区? 
临时存储区称为缓冲区。所有标准输入和输出设备都包含一个输入和输出缓冲区。在标准 C/C++ 中,流被缓冲,例如在标准输入的情况下,当我们按下键盘上的键时,它不会发送到您的程序,而是由操作系统缓冲直到时间分配到那个程序。

它如何影响编程? 
在各种情况下,您可能需要清除不需要的缓冲区,以便在所需容器中而不是在前一个变量的缓冲区中获取下一个输入。比如C遇到“scanf()”后,如果需要输入字符数组或字符,而C++遇到“cin”语句后,需要输入字符数组或一个字符串,我们需要清除输入缓冲区,否则所需的输入被前一个变量的缓冲区占用,而不是被所需的容器占用。在第一次输入后在输出屏幕上按“Enter”(回车)时,由于前一个变量的缓冲区是新容器的空间(因为我们没有清除它),程序会跳过下面的输入容器。

从那些“Hello World”程序中升级。学习实现堆、堆栈、链表等数据结构!查看我们的**C 数据结构**课程,立即开始学习。

在C的情况下

#include<stdio.h>
int main()
{
	char str[80], ch;
	scanf("%s", str);
	ch = getchar();
	printf("%s\n", str);
	printf("%c", ch);	
	return 0;
}

输入:

Haiyong
a

输出: 

Haiyong

在C++的情况下

#include<iostream>
#include<vector>
using namespace std;

int main()
{
	int a;
	char ch[80];
	cin >> a;
	cin.getline(ch,80);
	cout << a << endl;
	cout << ch << endl;
	return 0;
}

输入: 

4 
Haiyong

输出: 

4

在上面的两个代码中,输出都没有按需要打印。这样做的原因是一个被占用的缓冲区。“\n”字符留在缓冲区中,并作为下一个输入读取。

如何解决?

在C的情况下:  

1. 使用“ while ((getchar()) != '\n'); ”  : 输入“while ((getchar()) != '\n');” 读取缓冲区字符直到结束并丢弃它们(包括换行符)并在“scanf()”语句清除输入缓冲区并允许在所需容器中输入后使用它。

#include<stdio.h>

int main()
{
	char str[80], ch;
	scanf("%s", str);
	while ((getchar()) != '\n');
	ch = getchar();
	printf("%s\n", str);
	printf("%c", ch);

	return 0;
}

输入: 

Haiyong 
a

输出: 

Haiyong 
a

2. 使用“ fflush(stdin) ” :在“scanf()”语句之后输入“fflush(stdin)”也会清除输入缓冲区,但避免使用它,根据C,输入流被称为“未定义” ++11 标准。

在C++的情况下:  

1. 使用“cin.ignore(numeric_limits::max(),'\n'); ”  :- 输入“cin.ignore(numeric_limits::max(),'\n');” 在“cin”语句丢弃输入流中的所有内容之后,包括换行符。

#include<iostream>
#include<ios>	
#include<limits>
using namespace std;

int main()
{
	int a;
	char str[80];
	cin >> a;
	cin.ignore(numeric_limits<streamsize>::max(),'\n');
	cin.getline(str, 80);
	cout << a << endl;
	cout << str << endl;
	return 0;
}

输入: 

4 
Haiyong

输出: 

4 
Haiyong

2. 使用“cin.sync()”: 在“cin”语句之后输入“cin.sync()”会丢弃缓冲区中剩余的所有内容。尽管“cin.sync()”并不适用于所有实现(根据 C++11 及以上标准)。

#include<iostream>
#include<ios>	
#include<limits>
using namespace std;

int main()
{
	int a;
	char str[80];
	cin >> a;
	cin.sync();
	cin.getline(str, 80);
	cout << a << endl;
	cout << str << endl;
	return 0;
}

输入: 

4 
Haiyong

输出: 

4

3. 使用“cin >> ws”: 在“cin”语句后输入“cin>>ws”告诉编译器忽略缓冲区并丢弃字符串或字符数组实际内容之前的所有空格。

#include<iostream>
#include<vector>
using namespace std;

int main()
{
	int a;
	string s;
	cin >> a;
	cin >> ws;
	getline(cin, s);
	cout << a << endl;
	cout << s << endl;
	return 0;
}

输入: 

4 
Haiyong

输出: 

4 
Haiyong