getch() 并将常规键与箭头键混合
getch() and mixing regular keys with arrow keys
我无法让文本显示在控制台上,也没有正确保存。我得到了箭头键、回车键、退格键和 escpe 功能。
还有一个我没有真正得到的/小/错误是当我按 esc 键并且它从空白退出时我被引导到这段代码
#endif /* defined (_M_IX86) || defined (_M_X64) */
__fastfail(FAST_FAIL_STACK_COOKIE_CHECK_FAILURE);
在 gc_report.c 中,我没有找到关于(或至少与我的问题相关)的详细信息。
#define KEY_UP 72
#define KEY_DOWN 80
#define KEY_LEFT 75
#define KEY_RIGHT 77
#define KEY_ENTER 13
#define KEY_BACKSPACE 8
#define KEY_ESCAPE 27
void texteditor(int x, int y,int kolommen,char textarr[20][20],int rijen=20)
{
int index = 0, indey = 0, keuze,lol = 20;
do{
gotoxy(index + x, indey + y);
keuze = 0;
keuze = _getch();
if (keuze == 0 || keuze == 0xE0 || keuze == 224)
{
keuze = _getch();
gotoxy(index + x, indey + y);
switch (keuze)
{
case KEY_UP:indey--;
break;
case KEY_LEFT: index--;
break;
case KEY_DOWN:indey++;
break;
case KEY_RIGHT: index++;
break;
}
indey = (indey <= 0) ? 0 : (indey > kolommen) ? kolommen : indey;
index = (index <= 0) ? 0 : (index > rijen) ? rijen : index;
}
if (keuze == 32 || (keuze >= 46 && keuze <= 57) || (keuze <= 64 && keuze >= 126))
{
textarr[index][indey] = (char)keuze;
std::cout << textarr[index][indey];
index++;
index = (index <= 0) ? 0 : (index > rijen) ? rijen : index;
}
if (keuze == KEY_BACKSPACE)
{
index = index--;
gotoxy(index + x, indey + y);
std::cout << " ";
index = (index <= 0) ? 0 : (index > rijen) ? rijen : index;
}
if (keuze == KEY_ENTER)
{
index = 0;
indey++;
indey =(indey >= kolommen) ? kolommen : indey++;
}
} while (keuze != KEY_ESCAPE);}
我也搜索了一下箭头键后面的值,其中我发现37(左箭头),38(向上箭头),39(右箭头),40(向下箭头)作为ASCII值,然后和我的有什么区别?
代码基于 ansi.sys
(现代 Windows 上的 运行 需要一些附加组件)。您没有确定您使用的是哪个附加组件。也许您将某些来源称为 Daniweb 文章 how to detect arrow keys??。
关于箭头键和 getch
(出于实用目的与 _getch
-- see Difference between getch() and _getch() 相同)的问题之前已回答:
- getch and arrow codes
- How to scan arrow keys from keyboard?
用于 left/right/up/down 的代码基于 ansi.sys
识别的转义序列的 final 字符,例如,(根据 ncurses):
kcub1=[=10=]K,
kcud1=[=10=]P,
kcuf1=[=10=]M,
kcuu1=[=10=]H,
但[=15=]
可能是其他字符,如3[
、0
,具体取决于配置。后者可能是 CPlusPlus 论坛上的Windows Extended Prefix Code as noted in Scan Codes。
顾名思义,ASCII字符集描述的是一个字符集,而不是键盘上的按键。因此,ASCII 中的箭头键没有值。
相反,您使用的 _getch()
函数返回 224
(E0h
) 或 0
以表明后面是键扫描代码。您为这些使用的值是正确的,您可以查找它们 here.
您找到的其他值 (37-40) 称为虚拟键,更为常见。例如,它们在 event.keyCode
和 available in the WinApi 的 Javascript 中返回,但它们不适用于您的 _getch()
示例。
既然已经解决了,让我们看看你的例子:
- 您可以删除
E0
,因为它等于 224
。
- 您正在使用的
textarr
数组的尺寸为 20x20。这意味着写超出 textarr[19][19]
是未定义的行为。在使用 rijen
作为替代索引之前,您正在比较数组索引 比 20 大 。您应该将 rijen
改为 19
。这样你就没有越界访问。
- 我会把
kolommen
放在 rijen
旁边。在它们之间放置数组是没有意义的 + 它会阻碍您为其设置默认值。
- 您还忽略了很多可打印字符。你应该构建你的代码以在最后有一个 else 条件,然后你用
isprint()
检查它是否可打印然后打印它。
- 现在是主要部分:
if (... || (keuze <= 64 && keuze >= 126))
。你看到问题了吗?我猜你的意思是 (keuze >= 64 && keuze <= 126)
。现在你忽略了所有的 ASCII 字母。
- 也许您想在开始前清屏 运行
texteditor()
。 system("cls")
是执行此操作的标准 Windows 方式。
另一件事,嵌套三元表达式很丑陋。您用于条件的不需要的括号在第二个三元表达式周围会好得多。此外,windows 控制台默认为 80x25,您可能希望使用它来代替 20x20。
最后,conio.h
是 non-standard header,您最好改用 <windows.h>
中的功能。或者完全摆脱 Windows 中的次优终端处理,并使用像 ncurses 这样的库和适当的终端。
我无法让文本显示在控制台上,也没有正确保存。我得到了箭头键、回车键、退格键和 escpe 功能。
还有一个我没有真正得到的/小/错误是当我按 esc 键并且它从空白退出时我被引导到这段代码
#endif /* defined (_M_IX86) || defined (_M_X64) */
__fastfail(FAST_FAIL_STACK_COOKIE_CHECK_FAILURE);
在 gc_report.c 中,我没有找到关于(或至少与我的问题相关)的详细信息。
#define KEY_UP 72
#define KEY_DOWN 80
#define KEY_LEFT 75
#define KEY_RIGHT 77
#define KEY_ENTER 13
#define KEY_BACKSPACE 8
#define KEY_ESCAPE 27
void texteditor(int x, int y,int kolommen,char textarr[20][20],int rijen=20)
{
int index = 0, indey = 0, keuze,lol = 20;
do{
gotoxy(index + x, indey + y);
keuze = 0;
keuze = _getch();
if (keuze == 0 || keuze == 0xE0 || keuze == 224)
{
keuze = _getch();
gotoxy(index + x, indey + y);
switch (keuze)
{
case KEY_UP:indey--;
break;
case KEY_LEFT: index--;
break;
case KEY_DOWN:indey++;
break;
case KEY_RIGHT: index++;
break;
}
indey = (indey <= 0) ? 0 : (indey > kolommen) ? kolommen : indey;
index = (index <= 0) ? 0 : (index > rijen) ? rijen : index;
}
if (keuze == 32 || (keuze >= 46 && keuze <= 57) || (keuze <= 64 && keuze >= 126))
{
textarr[index][indey] = (char)keuze;
std::cout << textarr[index][indey];
index++;
index = (index <= 0) ? 0 : (index > rijen) ? rijen : index;
}
if (keuze == KEY_BACKSPACE)
{
index = index--;
gotoxy(index + x, indey + y);
std::cout << " ";
index = (index <= 0) ? 0 : (index > rijen) ? rijen : index;
}
if (keuze == KEY_ENTER)
{
index = 0;
indey++;
indey =(indey >= kolommen) ? kolommen : indey++;
}
} while (keuze != KEY_ESCAPE);}
我也搜索了一下箭头键后面的值,其中我发现37(左箭头),38(向上箭头),39(右箭头),40(向下箭头)作为ASCII值,然后和我的有什么区别?
代码基于 ansi.sys
(现代 Windows 上的 运行 需要一些附加组件)。您没有确定您使用的是哪个附加组件。也许您将某些来源称为 Daniweb 文章 how to detect arrow keys??。
关于箭头键和 getch
(出于实用目的与 _getch
-- see Difference between getch() and _getch() 相同)的问题之前已回答:
- getch and arrow codes
- How to scan arrow keys from keyboard?
用于 left/right/up/down 的代码基于 ansi.sys
识别的转义序列的 final 字符,例如,(根据 ncurses):
kcub1=[=10=]K,
kcud1=[=10=]P,
kcuf1=[=10=]M,
kcuu1=[=10=]H,
但[=15=]
可能是其他字符,如3[
、0
,具体取决于配置。后者可能是 CPlusPlus 论坛上的Windows Extended Prefix Code as noted in Scan Codes。
顾名思义,ASCII字符集描述的是一个字符集,而不是键盘上的按键。因此,ASCII 中的箭头键没有值。
相反,您使用的 _getch()
函数返回 224
(E0h
) 或 0
以表明后面是键扫描代码。您为这些使用的值是正确的,您可以查找它们 here.
您找到的其他值 (37-40) 称为虚拟键,更为常见。例如,它们在 event.keyCode
和 available in the WinApi 的 Javascript 中返回,但它们不适用于您的 _getch()
示例。
既然已经解决了,让我们看看你的例子:
- 您可以删除
E0
,因为它等于224
。 - 您正在使用的
textarr
数组的尺寸为 20x20。这意味着写超出textarr[19][19]
是未定义的行为。在使用rijen
作为替代索引之前,您正在比较数组索引 比 20 大 。您应该将rijen
改为19
。这样你就没有越界访问。 - 我会把
kolommen
放在rijen
旁边。在它们之间放置数组是没有意义的 + 它会阻碍您为其设置默认值。 - 您还忽略了很多可打印字符。你应该构建你的代码以在最后有一个 else 条件,然后你用
isprint()
检查它是否可打印然后打印它。 - 现在是主要部分:
if (... || (keuze <= 64 && keuze >= 126))
。你看到问题了吗?我猜你的意思是(keuze >= 64 && keuze <= 126)
。现在你忽略了所有的 ASCII 字母。 - 也许您想在开始前清屏 运行
texteditor()
。system("cls")
是执行此操作的标准 Windows 方式。
另一件事,嵌套三元表达式很丑陋。您用于条件的不需要的括号在第二个三元表达式周围会好得多。此外,windows 控制台默认为 80x25,您可能希望使用它来代替 20x20。
最后,conio.h
是 non-standard header,您最好改用 <windows.h>
中的功能。或者完全摆脱 Windows 中的次优终端处理,并使用像 ncurses 这样的库和适当的终端。