std::cin: empty the input buffer without blocking

前端 未结 1 2025
春和景丽
春和景丽 2021-01-23 20:36

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

相关标签:
1条回答
  • 2021-01-23 21:06

    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;
    }
    
    0 讨论(0)
提交回复
热议问题