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() 相同)的问题之前已回答:

用于 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.keyCodeavailable 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 这样的库和适当的终端。