您的位置:首页 > 其它

不用回车读取一个字符

2010-09-27 11:26 260 查看
今天看到一份shell源码,其中有用到不输入回车即可收到字符的功能,在这份源码中,它的作用是在shell中接收上下键,执行历史命令。

原始代码:

/* 如何实现不用回车,就能读取一个字符,此程序可以用来查看键盘的字符编码 */
/*
以“上方向键”为例,3个字符分别是27<esc>, 79<O>,和65<A>。A>
而上面的getch()函数中的read()函数1次只从标准输入读入1个字符,
所以在getch()读入1个字符返回后再次被调用时,标准输入的缓冲区中还有2个字符,
因此read()函数不会阻塞(尽管我们这时没有再按下任何键),而是读出第2个字符,
然后返回,然后又继续读入第3个字符。
所以按下1个方向键,getch()函数实际上被调用了3次。
*/

#include<stdio.h>
#include<termio.h>
#include<stdlib.h>

static struct termios tty;
void set_key();
void reset_key();
char getch();

main()
{
char a;
set_key();
while(1)
{
a=getch();
printf("%d%c/n",a,a);
if(a=='0')
break;
}
reset_key();
}
void set_key()
{
struct termios new_tty;
tcgetattr(0,&tty);
new_tty=tty;
new_tty.c_lflag&=~(ICANON|ECHO|ISIG);
new_tty.c_cc[VTIME]=0;
new_tty.c_cc[VMIN]=1;
tcsetattr(0,TCSANOW,&new_tty);
return;
}
void reset_key()
{
tcsetattr(0,TCSANOW,&tty);
return;
}
char getch()
{
int i;
char ch;
switch(i=read(0,&ch,1))
{
case -1:
printf("error/n");
exit(3);
case 0:
printf("error0/n");
exit(4);
}
return(ch);
}


升级版:

/* 改进版不用输入回车,自动获取字符, 这段代码的功能是屏蔽掉其它按键的输入,只接收ESC,
回车以及四个方向键的输入,并且显示用户的输入。如果用户按下ESC键,程序就会结束。*/

#include <stdio.h>
#include <termio.h>
static struct termios tty;
enum Key{None, KeyESCClick, KeyEnterClick,
KeyUpClick, KeyDownClick,
KeyLeftClick, KeyRightClick};
void set_key();
void reset_key();
enum Key getch();

int main(int argc, char *argv[])
{
enum Key a;
set_key();
while(1)
{
a=getch();
switch(a)
{
case KeyESCClick:
printf("esc/n");
reset_key();
return 0;
case KeyEnterClick:
printf("enter/n");
break;
case KeyUpClick:
printf("up/n");
break;
case KeyDownClick:
printf("down/n");
break;
case KeyLeftClick:
printf("left/n");
break;
case KeyRightClick:
printf("right/n");
break;
default:
break;
}
}
reset_key();
return 0;
}
void set_key()
{
struct termios new_tty;
tcgetattr(0,&tty);
new_tty=tty;
new_tty.c_lflag&=~(ICANON|ECHO|ISIG);
new_tty.c_cc[VTIME]=0;
new_tty.c_cc[VMIN]=1;
tcsetattr(0,TCSANOW,&new_tty);
return;
}
void reset_key()
{
tcsetattr(0,TCSANOW,&tty);
return;
}
/*
修改了getch函数,由于上下左右方向键的字符编码特殊,所以在read中如果一次读取只有一个字符,那么就是普通字符,
如果是三个字符,那么就是方向键,再通过判断最后一个字符的内容就可以确定是方向键中的那一个。
*/
enum Key getch()
{
int i;
char ch[3];
while((i = read(0, ch, 3)) != -1)
{
printf("get char num: %d/n", i);
switch(i)
{
case 1:
switch(ch[0])
{
case 0x1b:
return KeyESCClick;
case 0x0a:
return KeyEnterClick;
}
break;
case 3:
switch(ch[2])
{
case 'A':
return KeyUpClick;
case 'B':
return KeyDownClick;
case 'C':
return KeyRightClick;
case 'D':
return KeyLeftClick;
}
}
}
return None;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐