我使用了我的应用程序的一部分Sleep(5000)
(我需要等待 5 秒)
问题是,如果用户在这 5 秒内按下任何键盘键,这些键将在睡眠后被读取,这会导致我的应用出现问题。
睡眠后如何清空缓冲区?
我试过了cin.clear()
,setbuf(stdin, NULL)
但如果缓冲区中有多个字符,他们就无法清除缓冲区。
我使用了我的应用程序的一部分Sleep(5000)
(我需要等待 5 秒)
问题是,如果用户在这 5 秒内按下任何键盘键,这些键将在睡眠后被读取,这会导致我的应用出现问题。
睡眠后如何清空缓冲区?
我试过了cin.clear()
,setbuf(stdin, NULL)
但如果缓冲区中有多个字符,他们就无法清除缓冲区。
您正在使用的两个功能没有您期望的效果:
clear()
根本不影响缓冲区,而是清除错误标志。也就是说,如果读取失败,则会设置一个标志 ( std::ios_base::failbit
)。虽然设置了任何错误标志(还有更多),但流不会尝试读取任何内容。setbuf(0, 0)
影响流的内部缓冲区不存在(具有非空值的调用具有实现定义的含义,通常是“什么都不做”)。这通常是一个坏主意,因为它会导致流非常慢。此外,用户按下的键可能不会存储在此缓冲区中,而是存储在操作系统输入缓冲区中,直到它们被发送到应用程序(有特定于平台的方法来关闭操作系统输入缓冲区,例如,在 POSIX 上你'd 用于tcsetattr()
将输入设置为非规范模式)。在任何一种情况下,没有缓冲区并不能真正帮助您:用户很可能输入了有效的输入。正确的方法是尝试读取可用的输入,如果失败,则删除有问题的字符(或字符)。为此,您将尝试读取输入,如果失败,您将读取clear()
流和ignore()
一个或多个字符(此示例忽略一整行;ignore()
不带参数调用仅忽略一个字符):
T value;
while (!(std::cin >> value)) {
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
无论如何,您总是需要验证输入是否成功,而额外的几行只是添加了一些恢复代码。
清除键盘输入缓冲区的最简单方法是
while(kbhit()) getch();
只需将该代码放在程序中要清除缓冲区的任何位置。
所需的头文件是conio.h
这似乎适用于使用 Code::Blocks 编译的 Windows 10:
#include <conio.h>
/**
* clears keyboard buffer
*
* @author Shaun B
* @version 0.0.2
* @fixed 15-01-2016
*/
void clearKeyboardBuffer()
{
while (_kbhit())
{
_getche();
}
}
然后从 C++ 脚本中需要的位置调用。