A followup to this question.
How can I clear the input buffer?
sleep(2);
// clear cin
getchar();
I only want the character that was typ
Having a system supporting 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;
}