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()函數即可 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM