Chinaunix首页 | 论坛 | 博客
  • 博客访问: 170156
  • 博文数量: 78
  • 博客积分: 30
  • 博客等级: 民兵
  • 技术积分: 287
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-24 02:49
文章分类
文章存档

2013年(23)

2012年(55)

分类: C/C++

2013-05-13 14:04:23

    一般情况下终端在接收到回车键后接收数据,而我们使用man命令查看帮助文档时,会发现只要我们按下“q”键后就会退出而不需要再按一下回车键。我们在编程的时候同样可以达到这种效果,实现方法就是:利用"tcgetattr"和"tcsetattr"函数。
下面贴上代码:
代码的功能是接收用户输入数据,当用户输入时间超过5个单位时间或者输入字符达到20个时接收数据(不需要回车!此时的回车也当成普通字符接收了)。
无代码无真相
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <termios.h> /* 与终端有关的函数声明*/

  4. /* Linux, not Windowns. 大家可以查看一下 man stty 命令*/
  5. int main()
  6. {
  7.     char buf[20];
  8.     int num,i;
  9.     struct termios new; /* 控制终端状态的数据结构,可 man termios 查看*/
  10.     struct termios old;

  11.     tcgetattr(0,&old); /* 得到当前的终端状态 */
  12.     new = old;
  13.     /* ICANON取反,表示关闭输入行编辑模式,这样我们可以直接read字符,不用等着敲回车.
  14.      * ISIG取反,表示禁止信号,这样Crtl+c Crtl+s 就不会产生信号了,当你发现用户键入
  15.      * Crtl+c后,你可以自定义一个动作
  16.      */
  17.     new.c_lflag &= ~(ICANON | ISIG);
  18.     new.c_cc[VTIME] = 5;//终端等待时间(以十分之一秒为单位)
  19.     new.c_cc[VMIN] = 20;//终端接收字符个数(或的关系)
  20.     //终端等待5个单位时间或者接收字符达到20个
  21.     tcsetattr(0,TCSANOW,&new); /* 应用新的设置*/

  22.     num = read(0,buf,sizeof(buf)); /* 从标准输入读取字符*/
  23.     buf[num] = '\0';
  24.     printf("\n");
  25.     printf("buf:%s\n",buf); /* 控制字符打印不出来,所以不要相信printf函数*/
  26.     printf("debug_> we get %d chars [",num);
  27.     for(i = 0; i < num; i++) { /* ASCII值才是我们想要的,就是用它来比较是那个键按下了*/
  28.         printf("%#x ",buf[i]);
  29.     }
  30.     printf("]\n");

  31.     /*
  32.      * your codes ,你可以试试Crtl+f , Alt+a 上下左右键的字符编码
  33.      */

  34.     tcsetattr(0,TCSANOW,&old); /* 如果要退出程序,恢复旧的设置 */

  35.     return 0;
  36. }
struct termios结构体中至少包含下列成员:
tcflag_t c_iflag;  /* 输入模式 */ 
tcflag_t c_oflag; /* 输出模式 */ 
tcflag_t c_cflag; /* 控制模式 */ 
tcflag_t c_lflag; /* 本地模式 */ 
cc_t c_cc[NCCS] ; /* 控制字符 */
如何设置这些数据参考man手册。
中文man手册:


附:shell下的实现
用shell同样可以实现上述的功能(即不用输入回车键),用到的命令是stty。
查看stty配置用:stty -g(机器能认出的)或stty -a(人能认出的)
关闭行输入用:stty -icanon
设置最少输入字符个数用:stty min n(个数)
设置输入超时时间用:stty time n
设置输入不回显用:stty -echo
其他参数参见man stty  

下面给出一个shell的程序,功能是运行shell后在终端一直打印输出一句话,直到按下任意键退出:
无代码无真相

  1. #!/bin/bash
  2. #function:一直打印语句直到按下任意键(空格和回车除外)
  3. #author:Allen_fu
  4. #time:2012.01.05

  5. WORD=''
  6. SAVEDTTY=`stty -g` #保存stty的原有设置到SAVEDTTY中
  7. stty -icanon #关闭行输入模式,即不用按回车键
  8. stty min 0         #最小输入字符个数不限
  9. stty time 5 #等待时间为5个十分之一秒
  10. while [ 1 ]
  11. do
  12.     echo "this is a test,enter any key will quit!"
  13.     read WORD
  14.     if [ "$WORD" != "" ]
  15.     then
  16.         echo ""
  17.         echo "quit"
  18.         stty $SAVEDTTY #恢复原来的设置
  19.         exit 0
  20.     fi
  21.     sleep 1
  22. done

但是上面的回车和空格键不能打断,还在摸索中。哪位大神知道麻烦告诉小弟一下,先谢谢哈!
阅读(2351) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~