5.6 检测击键动作

曾经为MS-DOS编写程序的人们经常会在Linux系统中寻找一个与kbhit函数等同的函数,kbhit函数可在没有实际进行读操作之前检测是否某个键被按过。遗憾的是,他们找不到这样的函数,因为Linux系统中没有与其直接等同的函数。但UNIX程序员对此并不在意,因为在UNIX下编写的程序几乎不或很少忙于等待某个事件的发生。由于kbhit函数的主要用途就是等待某个击键动作的发生,所以在UNIX和Linux系统上未实现类似的函数。

但当需要移植MS-DOS下的程序时,如果能够模拟kbhit函数所完成的功能将会很方便。你可以用非标准输入模式来实现它。

实 验 你自己的kbhit函数

(1)程序开始是标准的程序头和一组对终端设置结构的声明,变量peek_character将用在测试击键动作的代码中,然后是程序后面会用到的一些函数的原型定义。

5.6 检测击键动作 - 图1

(2)main函数首先调用init_keyboard函数来配置终端,然后每隔一秒循环调用一次kbhit函数。如果按键为q,就退出循环并调用close_keyboard函数恢复终端为标准模式,最后退出程序。

5.6 检测击键动作 - 图2

5.6 检测击键动作 - 图3

(3)init_keyboard函数和close_keyboard函数分别在程序的开始和结束对终端进行配置。

5.6 检测击键动作 - 图4

(4)下面就是检测是否有击键动作的kbhit函数:

5.6 检测击键动作 - 图5

(5)按键对应的字符由下一个函数readch读取,它会将变量peek_character重置为-1以进入下一次循环。

5.6 检测击键动作 - 图6

运行这个程序,你将看到如下的输出结果:

5.6 检测击键动作 - 图7

实验解析

init_keyboard函数将终端配置为“read调用直到有字符可以读取时才返回”的工作模式(MIN=1, TIME=0)。kbhit函数将这个模式修改为“read调用检查输入并立刻返回”的工作模式(MIN=0, TIME=0)。最后,在程序退出前恢复终端的初始设置。

注意,在kbhit函数中,你实际上已将按键对应的字符读取了,但它只在需要时才通过readch函数返回。