【问题标题】:Capturing the HOME key with getchar()使用 getchar() 捕获 HOME 键
【发布时间】:2013-02-26 21:40:15
【问题描述】:

我正在为 Linux 上的控制台程序编写命令行界面。我希望能够在其中使用箭头之类的键。所以为了捕获代码,我使用了这个简单的程序:

int main()
{
    int c = 0;
    while (c != 3) { // ctrl-c
        c = getchar();
        printf("%d\n", c);
    }
}

这样做我在捕获 HOME 键时遇到了问题。在一台计算机上,我得到序列“27 91 72”,在另一台计算机上得到“27 79 72”,在第三台计算机上得到“27 91 49 126”。

我不知道为什么我在 HOME 和 END 键上得到如此不同的代码(箭头和 F1-F12 键在三台计算机上给出了相同的序列)。

有没有一种标准的方式来获取这个密钥,或者某种配置可以在所有机器上给我相同的序列?

【问题讨论】:

  • “特殊”键发送的转义码因终端类型而异,更糟糕的是,它们不一定形成前缀码。您应该使用curses 为您管理所有这些。
  • 顺便说一下,通常c 永远不会等于3,因为如果用户按下Ctrl-C,那么您将得到SIGINT 信号。
  • 这是一个比你想象的更复杂的问题......生成的代码取决于终端类型(文本控制台、xterm、gnome 或 kde 终端或 windows 命令行都不同在这方面)以及控制台驱动程序或 X 键盘映射设置。 Linux 文本终端 HOWTO,tldp.org/HOWTO/Text-Terminal-HOWTO.html 给出了一些起点,特别是参见第 6 节(一定要使用并遵循那里提供的链接)。如果您想以 可移植 的方式执行此操作(没有大量依赖于术语类型的代码),请使用像 ncurses 这样的库。
  • 你可能想使用terminfo,如果不是诅咒的话

标签: linux terminal keyboard getchar


【解决方案1】:

你可以使用 curses 框架。

使用诅咒时,很容易获得特殊的按键。但缺点是你必须在链接时拉入整个curses库(例如使用gcc -lcurses),并且你必须在初始化的curses屏幕中使用所有curses函数。

#include <stdio.h>
#include <curses.h>

int main()
{
    int c = 0;
    initscr();
    keypad(stdscr, 1);
    c = getch();
    endwin();
    printf("0x%04x\n", c);
    printf("0x%04x\n", KEY_HOME);
}

这将初始化标准屏幕(stdscr),启用其中的键盘并使用 getch() 获得按键,然后再次关闭 stdscr 以恢复 tty 模式。

您还可以使用 has_key() 函数检查当前终端是否支持特殊键。

这是最简单的方法..

【讨论】:

  • 我很欣赏这个答案,但不幸的是我需要这个用于嵌入式设备,并且 curses 库不可用。
  • @Akobold: curses 是免费软件,它使用的terminfo DB 也是如此。你使用哪一个并不重要,就像不重新发明轮子 ...
  • 我的意思是为您的嵌入式环境编译ncurses,即使在必要时先移植它,也会节省您的时间。
  • 只要您可以控制应用程序运行的环境,您也可以硬编码您在嵌入式设备上获得的序列——这对于这个嵌入式设备来说可能会随着时间的推移而稳定?所以你不需要重新发明轮子(正如弗兰克所说),也不需要与真实的终端设置进行比较?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-28
  • 1970-01-01
  • 1970-01-01
  • 2015-06-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-14
相关资源
最近更新 更多