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

Jinku Hu 2023年10月12日
清除 C++ 中的输入缓冲区

本文将演示如何在 C++ 中清除输入缓冲区的多种方法。

使用 std::cin::ignore 函数清除 C++ 中的输入缓冲区

ignorestd::cin 对象的内置函数,可用于从输入流中提取和丢弃字符,直到指定的分隔符为止。在我们讨论 cin::ignore 函数的行为之前,应该注意到作为 cin/cout 的标准输入和输出流是缓冲的,这意味着在用户的写/读和操作系统内核的实际缓冲状态之间有一些簿记发生。该缓冲区由 C++ 库本身管理,其目的是使读/写请求更有效。请注意,为每个字节调用操作系统服务将导致 CPU 资源的使用效率非常低下,因此使用中间缓冲区来累积一些请求,然后使用单个请求来调用操作系统。

因此,cin::ignore 可以丢弃缓冲区中的剩余字节,当有连续调用时,这些字节可能会意外读取。下面的示例代码旨在更清晰地演示忽略行为。我们实现了一个无限的 while 循环,该循环从 cin 流中读取三个整数并将它们存储在相应的变量中。整数被打印到 cout 上,然后在下一次迭代中执行例程。请注意,用户在第一次迭代中可能会提供三个以上的整数。在这种情况下,cin.ignore 之前的代码将仅存储其中的 3 个,其他代码仍将存在于中间缓冲区中。现在,如果未使用给定参数调用 cin.ignore,则下一次迭代 cin >> 行将读取其余输入内容,并且将发生不一致的行为。在这种情况下,可以使用 cin.ignore 调用来丢弃输入,直到遇到给定字符为止。在这种情况下,我们指定了一个换行符,通常用于缓冲 cin 流。

#include <iostream>
#include <limits>
#include <sstream>

using std::cin;
using std::cout;
using std::endl;
using std::numeric_limits;

int main() {
  while (true) {
    int i1, i2, i3;
    cout << "Type space separated numbers: " << endl;
    cin >> i1 >> i2 >> i3;
    if (i1 == 0) exit(EXIT_SUCCESS);
    cin.ignore(numeric_limits<std::streamsize>::max(), '\n');
    cout << i1 << "; " << i2 << "; " << i3 << endl;
  }

  return EXIT_SUCCESS;
}

输出(带有示例用户输入):

Type space separated numbers:
12 32 54
12; 32; 54

另外,我们可以实现另一个示例代码,该示例代码接受两个由空格分隔符分隔的字符串。在这种情况下,用户可能会提供两个以上的名称,这将迫使此代码在 2 个以空格分隔的字符串之后删除所有首字母缩写。如果用户输入中只有一个名称和一个空格,则将始终终止 cin 输入的换行符存储为第二个首字母。后一种行为可以通过在 << name << surname 语句之后添加单个字符输出来证明。

#include <iostream>
#include <limits>
#include <sstream>

using std::cin;
using std::cout;
using std::endl;
using std::numeric_limits;

int main() {
  char name, surname;
  cout << "Type your name and surname: ";
  name = cin.get();
  cin.ignore(numeric_limits<std::streamsize>::max(), ' ');
  surname = cin.get();

  cout << "Your initials are: " << name << surname << endl;

  return EXIT_SUCCESS;
}

输出(带有示例用户输入):

Type your name and surname: Lama Lime
Your initials are: LL
``
作者: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

DelftStack.com 创始人。Jinku 在机器人和汽车行业工作了8多年。他在自动测试、远程测试及从耐久性测试中创建报告时磨练了自己的编程技能。他拥有电气/电子工程背景,但他也扩展了自己的兴趣到嵌入式电子、嵌入式编程以及前端和后端编程。

LinkedIn Facebook

相关文章 - C++ IO