_kbhit() for Linux【在linux上实现类似_kbhit()的功能】

来源:互联网 发布:苗族 知乎 编辑:程序博客网 时间:2024/05/01 17:43

【摘自:http://www.flipcode.com/archives/_kbhit_for_Linux.shtml】

_kbhit() for Linux
  Submitted by Morgan McGuire

The Windows_kbhit() function returns a nonzero value when a character is waiting in stdin,otherwise it returns zero. It does not consume the character and doesnot block. A common use of this function is to test when the user haspressed a key in an interactive console application. POSIX (andtherefore Linux) lacks a similar function. Although it does notdirectly support this functionality, the GNU Curses library can be used to implement_kbhit() on Linux. Here I present analternate solution to Curses that implements_kbhit() using only standard libraries. It should port directly to OS X, AIX, andother Unix-like operating systems as well as Linux. This implementation has two advantages over a Curses based approach. The Curses library must be initialized from main() before it can be used.This implementation is a drop-in replacement for_kbhit() when porting from Windows and does not require any explicit initialization.Also, no external library must be installed and linked.

The ioctl() function is a low level method for controlling I/O drivers. Its arguments depend on the stream and driver being used. The last group of lines in_kbhit() uses this function to determine whether data is waiting on stdin. This implementation was written specifically for Linux and may not port. A more general implementation can replace these lineswith a call to theselect() function as follows:

    timeval timeout;    fd_set rdset;    FD_ZERO(&rdset);    FD_SET(STDIN, &rdset);    timeout.tv_sec  = 0;    timeout.tv_usec = 0;    return select(STDIN + 1, &rdset, NULL, NULL, &timeout);  
Console input is typically line buffered on Linux, particularly when running over Telnet or SSH. This means that a keypress does not appear on stdin until a newline character is sent. The ioctl() or select() calls cannot determine if characters are in the buffer waiting for a newline, and can indicate that there are zero characters waiting when really several keys have been pressed.

To fix this, the first code block in _kbhit() disables line buffering. This uses routines from the termios.h header. Another author offers alonge rmethod that uses only ioctl() and avoids termios.h.Because termios.h is a standard header on most systems I see no reason to avoid it. Both implementations use a static variable to detect thefirst call and disable buffering then. Output buffering on stdout is still enabled. If you wish to print to stdout and see the result before a newline is sent, use the command flush(stdout) as shown in the simple demo.

The Linux version of _kbhit() now performs to the same specification as the Windows version. The actual value of thenon-zero integer returned will be different on the two platforms,however.

Morgan McGuire

-----------------------------------------------------------------------------------------------------------------------------------

相关文件 kbhit.txt :

/** Linux (POSIX) implementation of _kbhit(). Morgan McGuire, morgan@cs.brown.edu */#include <stdio.h>#include <sys/select.h>#include <termios.h>#include <stropts.h>#include <sys/ioctl.h> //不加这个头文件会导致FIONREAD未定义的错误int _kbhit() {    static const int STDIN = 0;    static bool initialized = false;    if (! initialized) {        // Use termios to turn off line buffering        termios term;        tcgetattr(STDIN, &term);        term.c_lflag &= ~ICANON;        tcsetattr(STDIN, TCSANOW, &term);        setbuf(stdin, NULL);        initialized = true;    }    int bytesWaiting;    ioctl(STDIN, FIONREAD, &bytesWaiting);    return bytesWaiting;}////////////////////////////////////////////////    Simple demo of _kbhit()#include <unistd.h>int main(int argc, char** argv) {    printf("Press any key");    while (! _kbhit()) {        printf(".");        fflush(stdout);        usleep(1000);    }    printf("\nDone.\n");    return 0;} 


相关问题的网址:

http://cboard.cprogramming.com/c-programming/63166-kbhit-linux.html

	
				
		
原创粉丝点击