摘要:一般情况下,我们在终端输入一些字符,输入的同时可以编辑(增加,删除,修改),然后输入回车,这些字符被送到缓冲区。但是,在more程序和其他的程序中,比如游戏中的快捷键,我们需要的是不用输入回车就可以读取字符。此时,我们就需要了解如何控制终端,使得在不输入回车的情况下就可以读入字符。
首先,我们看一下这个程序的实现:
#include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<sys/ioctl.h> int kbhit(); int main(int argc, char *argv[]) { int i=0; int c=' '; system("stty raw -echo"); printf("enter q to quit\n"); for (; c!='q';i++) { if (kbhit()) { c=getchar(); printf("\n got %c, on iteration %d",c,i); } } system("stty cooked echo"); return 0; } int kbhit() { int i; ioctl(0,FIONREAD,&i); return i; }
解析:
system:调用shell来执行相关命令
stty raw:将终端设置为阻塞模式,实现实时读取
ioctl:查询键盘缓冲区状态
函数名: ioctl
头文件:#include<sys/ioctl.h>
功 能: 控制I/O设备 ,提供了一种获得设备信息和向设备发送控制参数的手段。用于向设备发控制和配置命令 ,有些命令需要控制参数,这些数据是不能用read / write 读写的,称为Out-of-band数据。也就是说,read / write 读写的数据是in-band数据,是I/O操作的主体,而ioctl 命令传送的是控制信息,其中的数据是辅助的数据。
用 法: int ioctl(int handle, int cmd,[int *argdx, int argcx]);
返回值:成功为0,出错为-1
FIONREAD : 通过由ioctl的第三个参数指向的整数返回当前在本套接口接收缓冲区中的字节数。本特性同样适用于文件,管道和终端。