C / C++ – kbhit() function in Linux

Linux에서는 Windows C / C++ 라이브러리에서 제공되는 kbhit() 함수 (keyboard event를 detect 하는 함수 : keystroke가 들어왔을때 이를 감지함)를 사용할 수 없다.

대신 아래의 오픈소스 snippet을 이용하여, kbhit() 함수를 직접 구현하면 된다. 코드의 출처는 Indra17 블로그 이다.


kbhit() function detecting keyboard hitting event, is provided by Windows C / C++ library. But it is not available in Linux.

Thus, you should implement your kbhit() function in your own.
The code below is open source snippet for kbhit(). Please refer to Indra17 blog (in Korean) for more information.


// There's no kbhit() function in linux if you want to use kbhit() function, use this code as below.
// reference : http://indra17.tistory.com/60

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <termios.h>

static struct termios initial_settings, new_settings;

static int peek_character = -1;

void init_keyboard()
{
    tcgetattr(0,&initial_settings);
    new_settings = initial_settings;
    new_settings.c_lflag &= ~ICANON;
    new_settings.c_lflag &= ~ECHO;
    new_settings.c_cc[VMIN] = 1;
    new_settings.c_cc[VTIME] = 0;
    tcsetattr(0, TCSANOW, &new_settings);
}

void close_keyboard()
{
    tcsetattr(0, TCSANOW, &initial_settings);
}

int _kbhit()
{
    unsigned char ch;
    int nread;

    if (peek_character != -1) return 1;
    new_settings.c_cc[VMIN]=0;
    tcsetattr(0, TCSANOW, &new_settings);
    nread = read(0,&ch,1);
    new_settings.c_cc[VMIN]=1;
    tcsetattr(0, TCSANOW, &new_settings);
    if(nread == 1)
    {
        peek_character = ch;
        return 1;
    }
    return 0;
}

int _getch()
{
    char ch;

    if(peek_character != -1)
    {
        ch = peek_character;
        peek_character = -1;
        return ch;
    }
    read(0,&ch,1);
    return ch;
}

int _putch(int c) {
    putchar(c);
    fflush(stdout);
    return c;
}

// use above functions in this way
int main()
{
    init_keyboard();

    while (1) {
        if (_kbhit()) {
            int ch = _getch();
            _putch(ch);
            switch (ch) {
                ...
            }
        }
    }
    close_keyboard();

    return 0;
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s