Problem with kbhit () [and getch ()] for Linux

while(ch != 'q') { printf("looping\n"); sleep(1); if(kbhit()) { ch = readch(); printf("you hit %c\n",ch); } } 

This code gives me a blocking getch () function. I am trying to use this code to capture down arrows.

Added: Attempting to capture key up arrow codes gives me 3 characters 27, 91 and 65. Using if / else, I try to match the pattern, but I get only 2 characters. The next one is captured by pressing the next key.

I want to capture complete words using getchar (), always looking for specific keys all the time (esc, del, etc.).

+2
c inputstream console getch
03 Oct '09 at 13:25
source share
2 answers

This example may help:

raw.c - raw mode demonstration

 /* Raw mode demo */ /* See exactly what is being transmitted from the terminal. To do this we have to be more careful. */ #include <stdio.h> #include <signal.h> #include <termios.h> #include <stdlib.h> #include <unistd.h> struct termios oldtermios; int ttyraw(int fd) { /* Set terminal mode as follows: Noncanonical mode - turn off ICANON. Turn off signal-generation (ISIG) including BREAK character (BRKINT). Turn off any possible preprocessing of input (IEXTEN). Turn ECHO mode off. Disable CR-to-NL mapping on input. Disable input parity detection (INPCK). Disable stripping of eighth bit on input (ISTRIP). Disable flow control (IXON). Use eight bit characters (CS8). Disable parity checking (PARENB). Disable any implementation-dependent output processing (OPOST). One byte at a time input (MIN=1, TIME=0). */ struct termios newtermios; if(tcgetattr(fd, &oldtermios) < 0) return(-1); newtermios = oldtermios; newtermios.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); /* OK, why IEXTEN? If IEXTEN is on, the DISCARD character is recognized and is not passed to the process. This character causes output to be suspended until another DISCARD is received. The DSUSP character for job control, the LNEXT character that removes any special meaning of the following character, the REPRINT character, and some others are also in this category. */ newtermios.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); /* If an input character arrives with the wrong parity, then INPCK is checked. If this flag is set, then IGNPAR is checked to see if input bytes with parity errors should be ignored. If it shouldn't be ignored, then PARMRK determines what character sequence the process will actually see. When we turn off IXON, the start and stop characters can be read. */ newtermios.c_cflag &= ~(CSIZE | PARENB); /* CSIZE is a mask that determines the number of bits per byte. PARENB enables parity checking on input and parity generation on output. */ newtermios.c_cflag |= CS8; /* Set 8 bits per character. */ newtermios.c_oflag &= ~(OPOST); /* This includes things like expanding tabs to spaces. */ newtermios.c_cc[VMIN] = 1; newtermios.c_cc[VTIME] = 0; /* You tell me why TCSAFLUSH. */ if(tcsetattr(fd, TCSAFLUSH, &newtermios) < 0) return(-1); return(0); } int ttyreset(int fd) { if(tcsetattr(fd, TCSAFLUSH, &oldtermios) < 0) return(-1); return(0); } void sigcatch(int sig) { ttyreset(0); exit(0); } int main() { int i; char c; /* Catch the most popular signals. */ if((int) signal(SIGINT,sigcatch) < 0) { perror("signal"); exit(1); } if((int)signal(SIGQUIT,sigcatch) < 0) { perror("signal"); exit(1); } if((int) signal(SIGTERM,sigcatch) < 0) { perror("signal"); exit(1); } /* Set raw mode on stdin. */ if(ttyraw(0) < 0) { fprintf(stderr,"Can't go to raw mode.\n"); exit(1); } while( (i = read(0, &c, 1)) == 1) { if( (c &= 255) == 0177) /* ASCII DELETE */ break; printf( "%o\n\r", c); } if(ttyreset(0) < 0) { fprintf(stderr, "Cannot reset terminal!\n"); exit(-1); } if( i < 0) { fprintf(stderr,"Read error.\n"); exit(-1); } return 0; } 

(backspace to stop the demo, origin )

+1
03 Oct '09 at 13:52
source share

I can not reproduce your problem:

 #include <unistd.h> #include <stdio.h> #include <ctype.h> #include "kbhit.h" /* http://linux-sxs.org/programming/kbhit.html */ int main(){ init_keyboard(); char ch='x'; while( ch != 'q' ){ printf("looping\n"); sleep(1); if( kbhit() ){ printf("you hit"); do{ ch = readch(); printf(" '%c'(%i)", isprint(ch)?ch:'?', (int)ch ); }while( kbhit() ); puts(""); } } close_keyboard(); } 
+3
Oct 03 '09 at 14:13
source share



All Articles