http://hi.baidu.com/jtntiivtemcnsue/item/90689ce172ee912c5a7cfb1b

编写过MS-DOS程序的人通常都会查找Linux下等同于kbhit的函数,这个函数会检测一个按键是否被按下而并不实际的读取。不幸的是他们并没有找到这样的函数,因为并没有直接等同的函数。Unix程序员并不会注意到这个遗漏,因为Unix的编程方式通常为程序应准备好等待事件的发生。因为这就是通常的kbhit的用法,所以Unix和Linux将其忽略了。

然而,当我们要由MS-DOS移植程序时,通常需要模拟kbhit,此时我们可以用非正规输入模式来做到。

试验--我们自己的kbhit

1 首先我们需要定义标准的头文件并且为终端设置声明了一个结构。peek_character用于测试一个按键是否被按下。然后我们定义了我们将会用到的函数的原型。

#include

#include

#include

#include

#include

static struct termios initial_settings, new_settings;

static int peek_character = -1;

void init_keyboard();

void close_keyboard();

int kbhit();

int readch();

2 main函数调用init_keyboard函数来配置终端,然后一秒循环一次,调用kbhit函数。如果按键检测为q,close_keyboard函数会返回正常行为并且退出程序。

int main()

{

int ch = 0;

init_keyboard();

while(ch != ‘q’) {

printf(“looping\n”);

sleep(1);

if(kbhit()) {

ch = readch();

printf(“you hit %c\n”,ch);

}

}

close_keyboard();

exit(0);

}

3 init_keyboard与close_keyboard在程序的开始和结束配置终端。

void init_keyboard()

{

tcgetattr(0,&initial_settings);

new_settings = initial_settings;

new_settings.c_lflag &= ~ICANON;

new_settings.c_lflag &= ~ECHO;

new_settings.c_lflag &= ~ISIG;

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);

}

4 下面是检测键盘按键的函数:

int kbhit()

{

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;

}

5 按下的按键是由下一个函数,readch,读取的,然后将peek_character为下一次循环设置为-1。

int readch()

{

char ch;

if(peek_character != -1) {

ch = peek_character;

peek_character = -1;

return ch;

}

read(0,&ch,1);

return ch;

}

当我们运行这个程序时,我们会得到下面的输出:

$ ./kbhit

looping

looping

looping

you hit h

looping

looping

looping

you hit d

looping

you hit q

$

工作原理

在init_keyboard中配置终端在返回之前(MIN=1,TIME=0)读取一个字符。kbhit将其改变为检测输入并且立即返回(MIN=0,TIME=0),然后在程序退出前恢复原始设置。

注意,我们必须读取被按下的键,但是却是在局部存储,从而可以在需要的时候返回。

虚拟控制台

Linux提供了一个称之为虚拟控制台的特性。有许多的终端设备可用,所有的设备都共享PC的屏幕,键盘以及鼠标。通常,一个Linux的安装配置12个这样的虚拟控制台。

虚拟控制台是通过字符设备/dev/ttyN来访问的,在这里N是一个数字,由1开始。

如果我们的Linux系统使用文本登陆,那么在Linux启动运行时我们就会得到一个登陆提示。然后我们可以使用用户名与密码进行登陆。此时我们使用的设备就是第一个虚拟控制台,终端设备/dev/tty1。

使用who与ps命令,我们可以看到登陆的用户,shell与在这个虚拟控制台上正运行的程序:

$ who

neil      tty1    Mar   8 18:27

$ ps -e

PID TTY          TIME CMD

1092 tty1     00:00:00 login

1414 tty1     00:00:00 bash

1431 tty1     00:00:00 emacs

从这里我们可以看出登陆的用户为neil,并且在控制台设备/dev/tty1上运行Emacs。

Linux通常启动一个getty进程运行在前六个虚拟控制台上,这样就可以使用相同的屏幕,键盘与鼠标登陆六次。我们可以使用ps看到这些进程:

$ ps -e

PID TTY      TIME CMD

1092 tty1 00:00:00 login

1093 tty2 00:00:00 mingetty

1094 tty3 00:00:00 mingetty

1095 tty4 00:00:00 mingetty

1096 tty5 00:00:00 mingetty

1097 tty6 00:00:00 mingetty

在这里我们可以看到SuSE默认的getty程序,mingetty,运行在另外五个虚拟控制台上,等待用户登陆。

我们可以使用一个特殊的按键组合Ctrl+Alt+F来在虚拟控制台之间进行切换,在这里N为我们要切换到的虚拟控制台号。所以要切换到第2个虚拟控制台,我们需要按下Alt+Ctrl+F2,而Ctrl+Alt+F1会返回到第一个控制台。(当由字符登陆而不是图形登陆切换时,Ctrl+F组合也可以起作用)

如果Linux启动一个图形登陆,或者是通过startx或者是通过一个显示管理器,例如xdm,X Window系统将会使用第一个空闲的虚拟控制台来启动登陆,通常为/dev/tty7。当使用X Window系统时,我们可以使用Ctrl+Alt+F切换到文本控制台,并使用Ctrl+Alt+F7返回到图形控制台。

通常在Linux上会运行多个会活。如果我们这样做,例如,使用命令

$ startx - :1

Linux会在下一个空闲的虚拟控制台上启动X服务器,在这种情况下,通常为/dev/tty8,然后我们可以使用Ctrl+Alt+F8与Ctrl+Alt+F7在他们之间进行切换。

在所有其他方面,虚拟控制台的行为与终端类似,正如我们在这一章所描述的。如果一个进程具有正确的权限,虚拟控制台可以使用与通常的终端相的方式执行打开,读取与写入等操作。

伪终端

许类Unix系统,包括Linux,具有一个名为伪终端的特性。这些设备的行为与我们在这一章所使用的终端相类似,所不同的是他们并没有与其相关联的硬件。他们可以用来为其他的程序提供一个类终端接口。

例如,使用两个伪终端就可以使得两个象棋程序彼此交战,尽管程序本身是设置用来与人在终端进行交互的。作为中介的程序将一个程序的动作传递给另一个。可以使得伪终端可以使得程序在不提供终端的情况下像通常一样运行。

伪终端曾经是以特定系统的方式实现的。现在他们已经进入Single Unix规范的Unix98伪终或是PTY标准中。

总结

在这一章,我们了解了控制终端的三个不同方面。在这一章的第一部分,我们了解了重定向检测以及如何与一个终端交互,尽管标准的文件描述符已经进行重定向。我们讨论的硬件模型及其历史。然后我们了解了通用终端接口以及在Linux终端处理上提供详细控制的termios结构。我们也看到了如何使用termios数据库以及以独立于终端的方式管理屏幕的相关函数,同时我们也了解了立即检测按键。最后,我们讨论了Linux虚拟控制台以及伪终端。

另外:

linux下如何处理键盘响应,有没有类似bioskey(0)的函数

linux kbhit扫描键盘,(转)检测按键(Linux中kbhit()函数的实现)相关推荐

  1. 雷蛇linux识别,雷蛇键盘配置工具 for linux

    Gaming on Linux is big business now, and many ardent gamers use a Razer keyboard or mouse. Razer doe ...

  2. linux图形界面键盘切换输入法,解决linux下不同图形环境的输入法切换问题

    相关说明: gedit /usr/share/doc/scim/README.Qt SCIM supports three different input modes -- XIM mode, GTK ...

  3. 跟着吴坚鸿学单片机——第16天:矩阵键盘的组合按键触发

    原文链接:第十六节:矩阵键盘的组合按键触发. 文章目录 原文 读后感 自我练习 原文 第十六节:矩阵键盘的组合按键触发. 开场白: 上一节讲了矩阵键盘单个触发的压缩代码编程.这节讲矩阵键盘的组合按键触 ...

  4. linux中c语言kbhit函数用法,检测按键(Linux中kbhit()函数的实现)

    编写过MS-DOS程序的人通常都会查找Linux下等同于kbhit的函数,这个函数会检测一个按键是否被按下而并不实际的读取.不幸的是他们并没有找到这样的函数,因为并没有直接等同的函数.Unix程序员并 ...

  5. 在linux下面实现检测按键(Linux中kbhit()函数的实现)

    //在linux下面实现检测按键(Linux中kbhit()函数的实现) #include <stdio.h> #include <termios.h> #include &l ...

  6. linux下面实现检测按键(Linux中kbhit()函数的实现)

    在linux下面实现检测按键(Linux中kbhit()函数的实现)   #include <stdio.h> #include <termios.h> #include &l ...

  7. 发送linux键盘消息,在C#程序中模拟发送键盘按键消息

    using System.Runtime.InteropServices; 引入键盘事件函数 [DllImport("user32.dll")] public static ext ...

  8. linux 存储映射lun 给_如何在 Linux 上扫描/检测新的 LUN 和 SCSI 磁盘 | Linux 中国

    导读:当 Linux 系统连接到 SAN(存储区域网络)后,你需要重新扫描 iSCSI 服务以发现新的 LUN.本文字数:3394,阅读时长大约:4分钟https://linux.cn/article ...

  9. linux系统下键盘按键的重新映射——xmodmap工具和xev工具

    虽然linux下小键盘还是不能用,但是找到一篇好文章 linux系统下键盘按键的重新映射--xmodmap工具和xev工具 文章目录 1. xev工具: 2. xmodmap工具 大家会不会有时候,感 ...

最新文章

  1. 深入理解javascript的闭包
  2. Filebeat的下载(图文讲解)
  3. linux下socket编程-TCP
  4. GDCM:gdcm::Global的测试程序
  5. 2012 人民搜索 实习生招聘 笔试题
  6. Asp.NetCore依赖注入和管道方式的异常处理及日志记录
  7. 【音频处理】IIR滤波器设计(一)Biquad 滤波器
  8. 微信警告小游戏“分享滥用”;小米千亿估值再被下调;Facebook 最大规模重组 | CSDN 极客头条...
  9. gin 如何返回html_Gin(三):与模板配合使用 tmpl,go web 开发最火框架之一
  10. 一、auto_test_base
  11. 数据分析人的职场天花板
  12. (三)云计算技术学习--OpenStack之KeyStone
  13. matlab二阶系统绘制bode图,二阶系统bode图
  14. Typora使用数学公式
  15. iOS 强制横屏的方法
  16. 电路板上的插头怎么拔下来_怎么从电路板上拆卸多针脚电子元器件
  17. NppFTP-Disconnected
  18. 服务器性能测试工具及实战,性能测试实战--《软件测试52讲》
  19. 新时期计算机网络通信发展现状与趋势
  20. [深度学习]Part1 Python学习进阶Ch23爬虫Spider——【DeepBlue学习笔记】

热门文章

  1. Spring中Controller和RequestMapping的详解
  2. 简单实现ReplaceAll(转)
  3. Android获取手机应用程序包的信息
  4. chorme 下载文件 保留 放弃_西部数码使用指南:保留数据重装以后sqlserver数据库不能启动(sql2008,sql2012)...
  5. ali arthas 火焰图_带你上手阿里开源的 Java 诊断利器:Arthas
  6. redis在容器里连接不上_Redis服务器被劫持风波,服务器相关知识共享学习
  7. python制作ios游戏_python自动化生成IOS的图标
  8. python 修改xml_如何在python中更新/修改XML文件?
  9. c语言弟弟的作业,教弟弟做作业作文500字
  10. linux1.0内核下载,《Linux 0.01 内核分析与操作系统设计》(Linxu 0.01Source)