[英]std::cin: empty the input buffer without blocking
这个问题的后续行动。
如何清除输入缓冲区?
sleep(2);
// clear cin
getchar();
我只想输入最后输入的字符,我想放弃程序睡眠时输入的任何内容。 有没有办法做到这一点?
另外,我不想主动等待清除cin,因此无法使用ignore()。
我的方法是获取缓冲区的当前大小,如果不等于0,则静默清空缓冲区。 但是,我还没有找到获取缓冲区大小的方法。 std :: cin.rdbuf()-> in_avail()总是为我返回0。 peek()也积极等待。
我不想使用ncurses。
具有支持tcgetattr / tcsetattr的系统:
#include <iostream>
#include <stdexcept>
#include <termios.h>
#include <unistd.h>
class StdInput
{
// Constants
// =========
public:
enum {
Blocking = 0x01,
Echo = 0x02
};
// Static
// ======
public:
static void clear() {
termios attributes = disable_attributes(Blocking);
while(std::cin)
std::cin.get();
std::cin.clear();
set(attributes);
}
// StdInput
// ========
public:
StdInput()
: m_restore(get())
{}
~StdInput()
{
set(m_restore, false);
}
void disable(unsigned flags) { disable_attributes(flags); }
void disable_blocking() { disable_attributes(Blocking); }
void restore() { set(m_restore); }
private:
static termios get() {
const int fd = fileno(stdin);
termios attributes;
if(tcgetattr(fd, &attributes) < 0) {
throw std::runtime_error("StdInput");
}
return attributes;
}
static void set(const termios& attributes, bool exception = true) {
const int fd = fileno(stdin);
if(tcsetattr(fd, TCSANOW, &attributes) < 0 && exception) {
throw std::runtime_error("StdInput");
}
}
static termios disable_attributes(unsigned flags) {
termios attributes = get();
termios a = attributes;
if(flags & Blocking) {
a.c_lflag &= ~ICANON;
a.c_cc[VMIN] = 0;
a.c_cc[VTIME] = 0;
}
if(flags & Echo) {
a.c_lflag &= ~ECHO;
}
set(a);
return attributes;
}
termios m_restore;
};
int main()
{
// Get something to ignore
std::cout << "Ignore: ";
std::cin.get();
// Do something
StdInput::clear();
std::cout << " Input: ";
std::string line;
std::getline(std::cin, line);
std::cout << "Output: " << line << std::endl;
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.