• 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(" ……
    ");    //测试每键入一次,打印几次
    	}
    	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
     tmp2=%d
    ",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 ↑
    ");
    				break;
    			case 59://F1
    				printf("This is F1
    ");
    				break;
    			default:
    				break;
    			}
    		}
    		else			//普通按键,如字母、数字、space,Esc等按键
    		{
    			switch (tmp)
    			{
    			case 32://空格
    				printf("This is Space
    ");
    				break;
    			case 27://Esc
    				printf("This is Esc
    ");
    				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()函数即可 

  • 相关阅读:
    [BJOI2019]排兵布阵
    关于DP题的状态定义转换和各种优化这档事
    容斥原理学习笔记
    莫比乌斯反演学习笔记
    每日进度
    每日进度
    每日进度
    每日进度
    每日进度
    每日进度
  • 原文地址:https://www.cnblogs.com/TaoR320/p/12680180.html
Copyright © 2020-2023  润新知