getch()并使用箭头键混合常规键

时间:2015-03-26 10:11:53

标签: c++ ascii arrow-keys getch

我无法在控制台上显示文本,也没有正确保存。我得到了箭头键,输入,退格和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值,然后是什么与我的区别?

2 个答案:

答案 0 :(得分:2)

顾名思义,ASCII字符集描述的是字符集,而不是键盘上的键。因此,ASCII中的箭头键没有值。

相反,您使用的_getch()函数返回224E0h)或0,表示以下内容是关键扫描代码。您对这些值使用的值是正确的,您可以查找它们here

您找到的其他值(37-40)称为虚拟键,更为常见。例如,它们在event.keyCodeavailable in the WinApi的Javascript中返回,但它们不适用于您的_getch()示例。

现在已经解决了这个问题,让我们来看看你的例子:

  • 您可以移除E0,因为它等于224
  • 您使用的textarr数组的尺寸为20x20。这意味着超越textarr[19][19]的写作是未定义的行为。在使用rijen作为替代索引之前,您正在比较更大的数组索引。您应该rijen19。这样你就没有越界限制。
  • 我会将kolommen放在rijen旁边。在它们之间放置数组是没有意义的,它会阻碍你设置它的默认值。
  • 你也忽略了很多可打印的角色。您应该将代码结构化为最终具有else条件,然后使用isprint()检查它是否可打印,然后将其打印出来。
  • 现在主要部分是:if (... || (keuze <= 64 && keuze >= 126))。你看到了问题吗?我想你的意思是(keuze >= 64 && keuze <= 126)。现在你忽略所有ASCII字母的方式。
  • 也许您想在开始运行texteditor()之前清除屏幕。 system("cls")是执行此操作的标准Windows方式。

另一件事,嵌套三元表达式是丑陋的。在第二个三元表达式周围,你用于条件的不需要的括号会好得多。此外,Windows控制台默认为80x25,您可能需要使用它而不是20x20。

最后,conio.h是一个非标准的标题,您最好使用<windows.h>中的功能。或者完全脱离Windows中的次优终端处理,并使用像ncurses这样的库和适当的终端。

答案 1 :(得分:0)

代码基于ansi.sys(需要在现代Windows上运行一些附加组件)。您没有确定您使用的是哪个加载项。也许您将某些来源称为Daniweb文章how to detect arrow keys??

有关箭头键和getch的问题(实际用途与_getch相同 - 请参阅Difference between getch() and _getch())之前已经得到解答:

用于左/右/上/下的代码基于ansi.sys识别的转义序列的 final 字符,例如(根据ncurses) :

    kcub1=\0K,   
    kcud1=\0P,  
    kcuf1=\0M,   
    kcuu1=\0H,

\0可能是其他字符,例如\033[\340,具体取决于配置。后者可能是Windows Extended Prefix Code,如CPlusPlus论坛上的Scan Codes所述。