Bootstrap

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

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

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

C 编程 的情况下


// C 代码解释为什么不清除输入缓冲区会导致不希望的输出
#include<stdio.h> 
int main() 
{
  char str[80], ch; 

  // 例如,扫描来自用户 Serven 的输入 
  scanf("%s", str); 

  // 扫描来自用户 - 'a' 的字符,例如
  ch = getchar(); 

  // 打印字符数组,打印“Serven”)
  printf("%s\n", str); 

  // 这不打印字符'a'
  printf("%c", ch); 

  return 0; 
}

输入:

Serven 
a

 输出:

Serven 

 C++的情况下 

// C++ 代码解释为什么不清除输入缓冲区会导致不需要的输出 
#include<iostream> 
#include<vector> 
using namespace std; 

int main() 
{
  int a; 
  char ch[80]; 

  // 输入来自用户的输入,例如输入4
  cin >> a; 

  // 从用户那里获取输入 -例如“Serven”
  cin.getline(ch,80); 

  // 打印 4 
  cout << a << endl; 

  // 打印字符串:这将不会被打印出来
  cout << ch << endl; 
  return 0; 
}

输入:

4 
serven 

输出:

4 

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

如何解决?

 C 的情况下:  

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

// C 代码解释为什么要添加“while ( (getchar()) != '\n');” 在“scanf()”语句刷新输入缓冲区之后
#include<stdio.h> 

int main() 
{ 
  char str[80], ch; 

  // 扫描用户输入 -
  // 例如 Serven
  scanf("%s", str); 

  //刷新标准输入
  //(清除输入缓冲区)
  while ((getchar()) != '\n'); 

  // 扫描来自用户的字符 -
  // 例如 'a'
  ch = getchar();

  // 打印字符数组,
  // 打印“Serven”)
  printf("%s\n", str); 

  // 打印字符a:这次会打印'a'
  printf("%c", ch);  

  return 0; 
}

输入:​​​​​​​

Serven 
a

输出:​​​​​​​

Serven
a

​​​​​​​

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

 C++ 的情况下:  

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

// C++ 代码解释如何“cin.ignore(numeric_limits <streamsize>::max(),'\n');” 丢弃输入缓冲区
#include<iostream>  

// 对于<streamsize> 
#include<ios>   

// 对于 numeric_limits
#include<limits> 
using namespace std; 

int main() 
{
  int a; 
  char str[80]; 

  // 输入
  //  4  
  cin >> a; 

  // 丢弃输入缓冲区
  cin.ignore(numeric_limits<streamsize>::max(),'\n'); 

  // 输入
  // 例如Serven
  cin.getline(str, 80); 

  // 打印 4 
  cout << a << endl; 

  // 字符串将会被打印
  cout << str << endl; 

  return 0; 
}

输入:​​​​​​​

4 
Serven 

输出: ​​​​​​​

4
Serven 

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

// C++ 代码解释如何“cin.sync();”
// 丢弃输入缓冲区
#include<iostream>  
#include<ios>   
#include<limits> 
using namespace std; 

int main() 
{ 
  int a; 
  char str[80]; 

  // 输入
  // - 4  
  cin >> a; 

  // 丢弃输入缓冲区
  cin.sync(); 

  // 输入
  // 例如Serven
  cin.getline(str, 80);  

  // 打印 4 
  cout << a << endl; 

  // 打印字符串 - 现在将打印字符串
  cout << str << endl; 

  return 0; 
}

输入: ​​​​​​​

4 
Serven

输出: 

4

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

// C++ 代码解释“cin >> ws”如何丢弃输入缓冲区以及字符串的初始空白

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

int main() 
{ 
  int a; 
  string s; 

  // 输入 
  // 4 
  cin >> a; 

  // 丢弃字符串的输入缓冲区和初始空格
  cin >> ws; 

  // 输入
  // 例如 serven
  getline(cin, s); 

  // 打印 4和 serven
  cout << a << endl; 
  cout << s << endl; 

  return 0; 
}

输入: ​​​​​​​

4 
Serven 

输出: ​​​​​​​

4 
Serven

;