コアダンプの数だけ強くなれるよ

見習いエンジニアの備忘log

linuxでkbhit()

LinuxWindowsのkbhit()相当を実装する。

kbhit.h

#ifndef _KBHIT_H_
#define _KBHIT_H_

#include <stdbool.h>
#include <termios.h>
#include <unistd.h>

extern void KB_open(void);
extern void KB_close(void);
extern bool kbhit(void);
extern char linux_getch(void);


#endif /* _KBHIT_H_ */


kbhit.c

#include "kbhit.h"

static struct termios Old_set;
static struct termios New_set;
static int ReadChar = -1;

void KB_open()
{
    tcgetattr(0,&Old_set);
    New_set = Old_set;
    New_set.c_lflag &= ~ICANON;
    New_set.c_lflag &= ~ECHO;
    New_set.c_lflag &= ~ISIG;
    New_set.c_cc[VMIN] = 0;
    New_set.c_cc[VTIME] = 0;
    tcsetattr(0,TCSANOW,&Old_set);
}

void KB_close()
{
    tcsetattr(0,TCSANOW, &Old_set);
}

bool kbhit()
{
    char ch;
    int nread;

    if(ReadChar !=-1) {
        return true;
    }

    New_set.c_cc[VMIN]=0;
    tcsetattr(0,TCSANOW,&New_set);
    nread=read(0,&ch,1);
    New_set.c_cc[VMIN]=1;
    tcsetattr(0,TCSANOW,&New_set);

    if(nread == 1) {
        ReadChar = ch;
        return true;
    }

    return false;
}

char linux_getch()
{
    char ch;

    if(ReadChar != -1) {
       ch = ReadChar;
       ReadChar = -1;
       return (ch);
    }

    read(0,&ch,1);
    return(ch);
}

main.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
    KB_open();

    while(1) {
        if (kbhit()) {

            char ch = linux_getch();

            printf("kbhit: %c\n", ch);

            if ('q' == ch) {
                break;
            }
        }

        usleep(10000);
    }

    KB_close();
}


Makefile

kbloop: kbhit.o main.o
        gcc -o kbloop kbhit.o main.o

kbhit.o: kbhit.h kbhit.c
        gcc -c kbhit.c

main.o: main.c
        gcc -c main.c

clean:
        rm -f *.o


実行例

$ make
gcc -c kbhit.c
gcc -c main.c
gcc -o kbloop kbhit.o main.o
$
$ ./kbloop
kbhit: a
kbhit: b
kbhit: c
kbhit: d
kbhit: e
kbhit: f
kbhit: g
kbhit: q
$
$