我正在编写一个使用getch()
扫描箭头键的程序。到目前为止我的代码是:
switch(getch()) {
case 65: // key up
break;
case 66: // key down
break;
case 67: // key right
break;
case 68: // key left
break;
}
问题是,当我按'A'
,'B'
,'C'
或'D'
时,代码也会执行,因为65
是{的十进制代码{1}}等等......
有没有办法检查箭头键而不打电话给其他人?
谢谢!
答案 0 :(得分:54)
按一个箭头键getch
会将三个值推入缓冲区:
'\033'
'['
'A'
,'B'
,'C'
或'D'
所以代码将是这样的:
if (getch() == '\033') { // if the first value is esc
getch(); // skip the [
switch(getch()) { // the real value
case 'A':
// code for arrow up
break;
case 'B':
// code for arrow down
break;
case 'C':
// code for arrow right
break;
case 'D':
// code for arrow left
break;
}
}
答案 1 :(得分:18)
getch()函数返回箭头键的两个键码(以及一些其他特殊键),如FatalError的注释中所述。它首先返回0(0x00)或224(0xE0),然后返回一个代码,用于标识按下的键。
对于箭头键,它首先返回224,然后是72(向上),80(向下),75(向左)和77(向右)。如果按下数字键盘箭头键(关闭NumLock),则getch()首先返回0而不是224.
请注意,getch()没有任何标准化,这些代码可能因编译器而异。这些代码由Windows上的MinGW和Visual C ++返回。
一个方便的程序,用于查看各种键的getch()操作:
#include <stdio.h>
#include <conio.h>
int main ()
{
int ch;
while ((ch = _getch()) != 27) /* 27 = Esc key */
{
printf("%d", ch);
if (ch == 0 || ch == 224)
printf (", %d", _getch ());
printf("\n");
}
printf("ESC %d\n", ch);
return (0);
}
这适用于MinGW和Visual C ++。这些编译器使用名称_getch()而不是getch()来表示它是非标准函数。
所以,你可以这样做:
ch = _getch ();
if (ch == 0 || ch == 224)
{
switch (_getch ())
{
case 72:
/* Code for up arrow handling */
break;
case 80:
/* Code for down arrow handling */
break;
/* ... etc ... */
}
}
答案 2 :(得分:2)
所以,经过多次斗争,我奇迹般地解决了这个棘手的问题! 我试图模仿一个linux终端并且卡在它保存命令历史的部分,可以通过按向上或向下箭头键来访问它。我发现ncurses lib很难理解,也很难学习。
char ch = 0, k = 0;
while(1)
{
ch = getch();
if(ch == 27) // if ch is the escape sequence with num code 27, k turns 1 to signal the next
k = 1;
if(ch == 91 && k == 1) // if the previous char was 27, and the current 91, k turns 2 for further use
k = 2;
if(ch == 65 && k == 2) // finally, if the last char of the sequence matches, you've got a key !
printf("You pressed the up arrow key !!\n");
if(ch == 66 && k == 2)
printf("You pressed the down arrow key !!\n");
if(ch != 27 && ch != 91) // if ch isn't either of the two, the key pressed isn't up/down so reset k
k = 0;
printf("%c - %d", ch, ch); // prints out the char and it's int code
它有点大胆,但它解释了很多。祝你好运!
答案 3 :(得分:2)
实际上,要读取箭头键,需要读取其扫描码。 以下是按箭头键(非键释放)生成的扫描码
当num Lock关闭时
当Num Lock开启时,这些键前面加上 E0 2A
字节50为80 DOWN
user_var=getch();
if(user_var == -32)
{
user_var=getch();
switch(user_var)
{
case 72:
cur_sel--;
if (cur_sel==0)
cur_sel=4;
break;
case 80:
cur_sel++;
if(cur_sel==5)
cur_sel=1;
break;
}
}
在上面的代码中,我假设程序员只想移动4行。
答案 4 :(得分:1)
keypad
将允许用户终端的键盘允许将功能键解释为单个值(即没有转义序列)。
如手册页所述:
键盘选项启用用户终端的键盘。如果 启用(bf为TRUE),用户可以按功能键(例如 箭头键)和wgetch返回表示该函数的单个值 key,如KEY_LEFT。如果禁用(bf为FALSE),curses不会处理 特别是功能键,程序必须解释逃逸 序列本身。如果可以打开终端中的键盘(制作 传输)和关闭(在本地工作),打开此选项 当调用wgetch时,会导致终端键盘打开。该 键盘的默认值为false。
答案 5 :(得分:0)
对于使用ncurses
的工作代码和ncurses初始化的解决方案,请参阅getchar() returns the same value (27) for up and down arrow keys
答案 6 :(得分:0)
我用getch编写了一个函数来获取箭头代码。它是一个快速的解决方案,但该函数将根据箭头键返回ASCII码: UP:-10 下:-11 右:-12 左:-13
此外,使用此功能,您可以区分ESCAPE触摸和箭头键。但你必须按ESC 2时间激活ESC键。
这里是代码:
char getch_hotkey_upgrade(void)
{
char ch = 0,ch_test[3] = {0,0,0};
ch_test[0]=getch();
if(ch_test[0] == 27)
{
ch_test[1]=getch();
if (ch_test[1]== 91)
{
ch_test[2]=getch();
switch(ch_test[2])
{
case 'A':
//printf("You pressed the up arrow key !!\n");
//ch = -10;
ch = -10;
break;
case 'B':
//printf("You pressed the down arrow key !!\n");
ch = -11;
break;
case 'C':
//printf("You pressed the right arrow key !!\n");
ch = -12;
break;
case 'D':
//printf("You pressed the left arrow key !!\n");
ch = -13;
break;
}
}
else
ch = ch_test [1];
}
else
ch = ch_test [0];
return ch;
}
答案 7 :(得分:0)
我只是一个初学者,但我创建了一个char(for example "b")
,我做b = _getch();
(它是一个conio.h
库的命令)
并检查
If (b == -32)
b = _getch();
并检查按键(72向上,向下80向,向右向右77向,75向左)
答案 8 :(得分:0)
尝试这个怎么样?
void CheckKey(void) {
int key;
if (kbhit()) {
key=getch();
if (key == 224) {
do {
key=getch();
} while(key==224);
switch (key) {
case 72:
printf("up");
break;
case 75:
printf("left");
break;
case 77:
printf("right");
break;
case 80:
printf("down");
break;
}
}
printf("%d\n",key);
}
int main() {
while (1) {
if (kbhit()) {
CheckKey();
}
}
}
(如果您无法理解为什么有224,那么请尝试运行此代码:)
#include <stdio.h>
#include <conio.h>
int main() {
while (1) {
if (kbhit()) {
printf("%d\n",getch());
}
}
}
但我不知道为什么会这样做224.如果你知道为什么,你能写下评论吗?
答案 9 :(得分:0)
void input_from_key_board(int &ri, int &ci)
{
char ch = 'x';
if (_kbhit())
{
ch = _getch();
if (ch == -32)
{
ch = _getch();
switch (ch)
{
case 72: { ri--; break; }
case 80: { ri++; break; }
case 77: { ci++; break; }
case 75: { ci--; break; }
}
}
else if (ch == '\r'){ gotoRowCol(ri++, ci -= ci); }
else if (ch == '\t'){ gotoRowCol(ri, ci += 5); }
else if (ch == 27) { system("ipconfig"); }
else if (ch == 8){ cout << " "; gotoRowCol(ri, --ci); if (ci <= 0)gotoRowCol(ri--, ci); }
else { cout << ch; gotoRowCol(ri, ci++); }
gotoRowCol(ri, ci);
}
}
答案 10 :(得分:0)
尝试一下...
我在Windows 7中使用Code :: Blocks
while (true)
{
char input;
input = getch();
switch(input)
{
case -32: //This value is returned by all arrow key. So, we don't want to do something.
break;
case 72:
printf("up");
break;
case 75:
printf("left");
break;
case 77:
printf("right");
break;
case 80:
printf("down");
break;
default:
printf("INVALID INPUT!");
break;
}
}