繁体   English   中英

std :: cin:清空输入缓冲区而不会阻塞

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM