ADAM'S WEB PRESENCE

2 February 2009

Reading a single keystroke with C++ on Linux

Filed under: Nerd Notes — adam @ 9:03 am

Just say you want to input a single key from your user such as asking “Would you like to continue [y/n] ?” without requiring the user to press ENTER. You’d think you could do it like this:

char c;
cin >> c;
cout << "You pressed " << c << endl;

But it doesn't work! The user has to press ENTER before the cin function will complete.

I read all sorts of crazy solutions on the web to fix this, most of which involve using NCURSES but I think that is total overkill. I have found a simpler way.

Now it's not the fault of std::cin or even C++. It's the operating system which buffers the keyboard input, only releasing it to your app when the user whacks ENTER. So what you need to do is tell the OS not to buffer keystrokes. You can do this with the termios functions in Linux. Here is an example:

// Example for inputting a single keystroke in C++ on Linux
// by Adam Pierce <adam@doctort.org>
// This code is freeware. You are free to copy and modify it any way you like.

#include <iostream>
#include <termios.h>

using namespace std;
main()
{
// Black magic to prevent Linux from buffering keystrokes.
    struct termios t;
    tcgetattr(STDIN_FILENO, &t);
    t.c_lflag &= ~ICANON;
    tcsetattr(STDIN_FILENO, TCSANOW, &t);

// Once the buffering is turned off, the rest is simple.
    cout << "Enter a character: ";
    char c = cin.get();
    cout << "Your character was " << c << endl;

    return 0;
}

Powered by WordPress