linux 读取键盘上下左右键小程序

月城雪兔 2016-06-03 17:28:31
因为想读取键盘的上下左右方向键,却发现在网上不容易找到恰当的例子,最后是以一个ros程序简化而来的。

第一,为什么在运行程序时,在终端按下箭头up down left right 箭头会出现 ^[A^[B^[C^[D

这个跟换键码有关,“escape sequence”实际上是用来生成换码符的关键字的顺序。换码符会告诉打印机将不再打印后面的字符,但是还要将这些字符解释为一类打印机控制码或其他。需要 Escape Sequences 顺序的应用程序通常是早期的 DOS 应用程序、UNIX (R) 应用程序或非常特殊的应用程序。

up - "\033[A"
down - "\033[B"
left - "\033[D"
right - "\033[C"

\033 = 0x1b = 27 = ^[= Esc 键 , 也就是说up down left right 这些键,每个都由三个字符组成。

读到键值为 读到27时,再读一个是'[' = 0x5B = 91, 然后再读一个键,若是'A' = 0x41 = 65则表示向上的箭头。其他的类似。

第二个知识点是关于signal()的。简单地说是我们在终端运行一个程序时,要想让这个程序终止可以同时按下Ctrl 和 c 键, 这是默认的.但是我们想要在结束一个程序之前,做一些我们想要事情,或是按下键盘,引起发射信号,执行我们想要执行的函数时,我们可以用signal()。如本例中的按下ctrl+c 执行quit()函数,在quit()函数中我们执行了其他函数。

软中断信号(signal,又简称为信号)用来通知进程发生了异步事件。
是在软件层次上对中断机制的一种模拟,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。内核也可以因为内部事件而给进程发送信号,通知进程发生了某个事件。
信号机制除了基本通知功能外,还可以传递附加信息。

收到信号的进程对各种信号有不同的处理方法。处理方法可以分为三类:
第一种是类似中断的处理程序,对于需要处理的信号,进程可以指定处理函数,由该函数来处理。
第二种方法是,忽略某个信号,对该信号不做任何处理,就象未发生过一样。
第三种方法是,对该信号的处理保留系统的默认值,这种缺省操作,对大部分的信号的缺省操作是使得进程终止。进程通过系统调用signal来指定进程对某个信号的处理行为。

linux主要有两个函数实现信号的安装:signal()、sigaction()。
其中signal()只有两个参数,不支持信号传递信息,主要是用于前32种非实时信号的安装;
而sigaction()是较新的函数(由两个系统调用实现:sys_signal以及sys_rt_sigaction),
有三个参数,支持信号传递信息,主要用来与 sigqueue() 系统调用配合使用,
sigaction()同样支持非实时信号的安装。sigaction()优于signal()主要体现在支持信号带有参数。

signal()
                                                               ------------
#include <signal.h>

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

DESCRIPTION
       The behavior of signal() varies across UNIX versions, and has also varied historically across
       different versions of Linux. Avoid its use: use sigaction instead. See Portability below.

signal() sets the disposition of the signal signum to handler, which is either SIG_IGN,
       SIG_DFL, or the address of a programmer-defined function (a "signal handler").

If the signal signum is delivered to the process, then one of the following happens:

* If the disposition is set to SIG_IGN, then the signal is ignored.
       * If the disposition is set to SIG_DFL, then the default action associated with the signal occurs.
       * If the disposition is set to a function, then first either the disposition is reset to SIG_DFL,
          or the signal is blocked, and then handler is called with argument signum. If invocation of the
          handler caused the signal to be blocked, then the signal is unblocked upon return from the
          handler.
          The signals SIGKILL and SIGSTOP cannot be caught or ignored.

RETURN VALUE
       signal() returns the previous value of the signal handler, or SIG_ERR on error.
       In the event of an error, errno is set to indicate the cause.

signum指定信号的值,第二个参数指定针对前面信号值的处理,可以忽略该信号(参数设为SIG_IGN);可以采用系统默认方式处理信号(参数设为SIG_DFL);也可以自己实现处理方式(参数指定一个函数地址)。

signal里的一个SIGQUIT和SIGINT。根据apue的解释,ctl+c产生SIGINT,而ctl+\产生SIGQUIT。
=======================================================================

#include <signal.h>
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>

#define KEYCODE_R 0x43
#define KEYCODE_L 0x44
#define KEYCODE_U 0x41
#define KEYCODE_D 0x42
#define KEYCODE_Q 0x71

int kfd = 0;
struct termios cooked, raw;

void quit(int sig)
{
  (void)sig;
  tcsetattr(kfd, TCSANOW, &cooked);//在程序结束时在恢复原来的配置
  exit(0);
}

void keyLoop()
{
  char c;

// get the console in raw mode
  tcgetattr(kfd, &cooked); // 得到 termios 结构体保存,然后重新配置终端
  memcpy(&raw, &cooked, sizeof(struct termios));
  raw.c_lflag &=~ (ICANON | ECHO);
  // Setting a new line, then end of file
  raw.c_cc[VEOL] = 1;
  raw.c_cc[VEOF] = 2;
  tcsetattr(kfd, TCSANOW, &raw);

puts("Reading from keyboard");
  puts("---------------------------");
  puts("Use arrow keys to move the robot.");
  puts("otherwise the key values will be printed");

for(;;)
  {
    // get the next event from the keyboard
    if(read(kfd, &c, 1) < 0)
    {
      perror("read():");
      exit(-1);
    }

switch(c)
    {
      case KEYCODE_L:
        printf("LEFT\n");
        break;
      case KEYCODE_R:
        printf("RIGHT\n");
        break;
      case KEYCODE_U:
        printf("UP\n");
        break;
      case KEYCODE_D:
        printf("DOWN\n");
        break;
          default:
                printf("value: %c = 0x%02X = %d\n", c, c, c);
    }
  }
  return;
}

int main(int argc, char** argv)
{
  signal(SIGINT,quit);

keyLoop();
  
  return(0);
}

linux 读取键盘上下左右键小程序相关推荐

  1. 如何解除计算机方向键问题,笔记本键盘上下左右键怎么解锁_笔记本电脑的上下左右键被锁住了如何解决-win7之家...

    我们在电脑中玩游戏的时候,经常会使用到键盘上下左右键来进行操作,不过有不少笔记本用户反映说键盘上下左右键被锁住了,导致无法操作,但是这种情况不多见,如果被锁定的话.一般是数字区域,方向键基本上没有被锁 ...

  2. 用键盘上下左右键和ctrl键移动TreeView节点

    /// <summary>/// 用键盘上下左右键和ctrl键移动节点 /// 思路:现复制2个选中的节点.1.为了记住第一次选中节点位置,2在上移过程中现将令一个插入指定位置,/// 然 ...

  3. layui table 可编辑单元格 JS实现通过键盘上下左右键 光标焦点移动到旁边的编辑行/列

    layui table 可编辑单元格 JS实现通过键盘上下左右键 光标焦点移动到旁边的编辑行/列 类似效果 上下左右键实现的代码 layui.config({base: '/static/layuia ...

  4. linux下的socket通信小程序分享——第三圣子

    第三圣子 最近学习unix网络编程,感觉东西零零碎碎,比较混乱.因此决定整理以下,发一个小博客.一来可以与大家分享以下,二来可以总结提高一下所学的东西.话说:竹子为什么长的高,因为它喜欢总结阿--^_ ...

  5. 为Linux Mint Cinnamon的日历小程序增加中国农历显示以及其它部分参数优化

    我最近使用Linux Mint Xfce的时间比较多,这个操作系统虽然运行效率高,占用资源少,但是感觉Xfce桌面稳定性还存在不足,经常出现莫名其妙的画面抖动及部分区域出现花屏的现象,还容易出现使用者 ...

  6. 键盘上下左右键返回的键值的问题

    在用getch()(在头文件conio.h)获得上下左右键的键值时候,他们是双键值,会返回高八位和低八位的int型数值. eg:int key1=getch() key2=getch() 在键盘中按下 ...

  7. linux通讯录软件带头像,小程序新技能 Get!保存微信好友头像到手机通讯录

    原标题:小程序新技能 Get!保存微信好友头像到手机通讯录 亲爱的朋友,你知道来电时能看到好友的头像是一种怎样的体验吗? 你是否注意过这样一件事:每当打开自己的微博.微信等社交软件,除了扑面而来的信息 ...

  8. JS实现用键盘上下左右键移动页面的div进行移动,并且不能移出页面

    <style>#box {width: 200px;height: 200px;background-color: red;position: fixed;} </style> ...

  9. 微信小程序 php读取数据,在微信小程序中如何获取输入数据

    这篇文章主要介绍了微信小程序简单实现form表单获取输入数据功能,涉及微信小程序针对form表单的事件绑定及数据获取等相关操作技巧,需要的朋友可以参考下 本文实例讲述了微信小程序简单实现form表单获 ...

最新文章

  1. test1---peersim 0
  2. 文献记录(part45)--Pedestrian detection with super-resolution reconstruction for low-quality image
  3. Hike on a Graph HDU - 1252(bfs)
  4. [智能架构系列]什么是Buddy智能开发框架
  5. Git学习(3)GitHub和SVN的区别
  6. c语言中a lt 1e-9,年9月计算机二级考试C语言强化训练题
  7. paip. mysql如何临时 暂时 禁用 关闭 触发器
  8. Xamarin教程索引页
  9. 2021数学建模A题详细思路
  10. 说说我出道后的处女作:剪贴板神器 iPaste
  11. 台式计算机关机后自行重启,台式电脑关机后自动重启怎么办?台式电脑关机后自动开机的处理办法...
  12. java 全角_java全角、半角字符的关系以及转换详解
  13. 鲁能群英荟萃 萝卜开会
  14. 攻防世界之misc1
  15. 风控术语手册(银行_消费金融信贷业务)_version6
  16. 如何在转换CAD图纸的时候更改背景颜色?
  17. Android手机基本教程
  18. H5的rem适配方案
  19. 如果房子5折甩卖,你会买吗?
  20. 劢领AT|五分钟,使用AT指令读写U盘文件

热门文章

  1. 东芝光耦TLP521-1智能型双电源开关控制器设计的实现
  2. 极客学院内部首发唯一完整实战微信小程序培训课程,现在免费赠送(价值500
  3. 对计算机课画图课的点评,四年级信息技术观摩课教案及评课:我用电脑学画画...
  4. JAVA调用微信投放卡券——HTML5线上发券(JS-SDK接口)
  5. Android(SpreadTurm)波斯文,阿拉伯语添加人联系人报错
  6. 朴素贝叶斯实战——判断肿瘤是良性还是恶性
  7. 合肥工业大学机器人技术作业一
  8. 营业执照OCR识别/营业执照识别优势
  9. Spring MVC JSP 表单标签教程
  10. 解析各大电子商务网站订单号的生成方式