清除 C++ 中的输入缓冲区
本文将演示如何在 C++ 中清除输入缓冲区的多种方法。
使用 std::cin::ignore
函数清除 C++ 中的输入缓冲区
ignore
是 std::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
``