2014-01-20 49 views
1

後續問題this問題。std :: cin:清空輸入緩衝區而不會阻塞

如何清除輸入緩衝區?

sleep(2); 
// clear cin 
getchar(); 

我只想要最後輸入的字符,我想放棄程序睡着時放入的任何輸入。有沒有辦法做到這一點?

此外,我不想等待主動清除cin,因此我不能使用ignore()。

我的方法是獲取緩衝區的當前大小,如果它不等於0,則靜靜地清空緩衝區。但是,我還沒有找到獲取緩衝區大小的方法。 std :: cin.rdbuf() - > in_avail()對我來說總是返回0。 peek()也在積極等待。

我不想使用ncurses。

+0

所以'sleep'完成和'getchar'開始利用類型的字符在這是否一個計數之前? –

+0

這是我還沒有考慮過的情況,但現在對這個問題並不重要。 – gartenriese

+0

@EdHeal:就我個人而言,我認爲這種情況和「睡眠期間」實際上難以區分,特別是因爲「睡眠(2)」是「2秒或更多」。 –

回答

1

有配套的系統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; 
}