getch()函数的使用方法及其返回值问题

getch()函数依赖于头文件 conio.h .会在windows平台下从控制台无回显地取一个字符,并且返回读取到的字符。

然而,我在实际用这个函数才发现getch()这个函数并不简单。

getch函数从控制台读取单个字符而不回显,函数不能去读取CTRL+C,当读取一个功能键或方向键,函数必须调用两次(这就说明可以用这个函数去监控功能键和方向键),第一次调用返回0或0xe0,第二次返回实际的键代码

例如:

#include <stdio.h>
#include <conio.h>
int main()
{
	while (true)
	{
		int tmp = _getch();
		printf(" ……\n");    //测试每键入一次,打印几次
	}
	return 0;
}

在这个简单的小程序中,我测试了几个键盘的按键。

  • 在a~z的英文字母、数字键、以及Tab、space、ESC、Backspace、Enter等几个常用键上,printf()只会打印一次,也就是说,getch()会立即返回真实的键码值,并且被tmp变量接收。
  • 在键盘上输入上下左右的方向键,F1~F9、Delete等功能键时,printf()会打印两次。

为了探究getch()的真相,我改写了以上函数。

int main()
{
	while (true)
	{
		int tmp = _getch();
		int tmp2 = _getch();
		printf(" tmp=%d\n tmp2=%d\n",tmp,tmp2);
	}
	return 0;
}

在键盘上依次输入上下左右得到如下键值:

  • 上     tmp=224     tmp2=72
  • 下     tmp=224     tmp2=80
  • 左     tmp=224     tmp2=75
  • 右     tmp=224     tmp2=77

上下左右方向键,getch()第一次返回 224(0xe0),第二次返回真实键值

在键盘上依次输入F1~F10、F11、F12、Delete得到如下键值: 

  • F1        tmp=0    tmp2=59
  • F2        tmp=0    tmp2=60
  • F3        tmp=0    tmp2=61
  • F10      tmp=0    tmp2=68

F1~F10,getch()第一次返回 0 ,第二次返回该键的真实键值(59~68)

  • F11         tmp=224    tmp2=133
  • F12         tmp=224    tmp2=134
  • Delete     tmp=224    tmp2=83

那么问题就来了,getch()一会返回一个值,一会返回两个值,究竟要怎样写才不会出错呢?

我这里提供一种方法,仅供参考

#include <conio.h>
int main()
{
	char tmp;	//读取键值,或过滤功能键的第一个返回值
	char tmp2;	//接受功能键
	while (true)
	{
		tmp = _getch();
		
		if (tmp == 0 || tmp == -32)//表示读取的是功能键或者方向键,丢掉第一个返回值,读取第二个返回值
		{
			switch (tmp2 = _getch())	//接収功能键返回值
			{
			case 72://上 
				printf("This is ↑\n");
				break;
			case 59://F1
				printf("This is F1\n");
				break;
			default:
				break;
			}
		}
		else			//普通按键,如字母、数字、space,Esc等按键
		{
			switch (tmp)
			{
			case 32://空格
				printf("This is Space\n");
				break;
			case 27://Esc
				printf("This is Esc\n");
				break;
			default:
				break;
			}
		}
		
	}
	return 0;
}

注意1:在以上代码中 tmp 为char类型,可接受的值为 -128~127之间,所以原本 0xe0的返回值(10进制为224) 会被转换为 -32。

转换原理为 超出char范围的(即127以后的数字),把差值从 char类型的另一侧极限值重新开始计算(即-128往后排)

例如:224——> 超出97(224-127)——> -128+97-1=-32 

详见char的越界赋值即其原理剖析

解决办法:

  1. 可以把tmp定义 unsigned char类型
  2. 通过计算、或者测试,得到可用的键值。

注意2:用getch()函数时,编译器可能会给出如下错误

严重性    代码    说明    项目    文件    行    禁止显示状态
错误    C4996     'getch': The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name: _getch. See online help for details.    
 

解决办法:把getch()换成编译器要求的_getch()函数即可 

发布了75 篇原创文章 · 获赞 88 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43919932/article/details/102234892
今日推荐