【问题标题】:Getting capital O from getchar when pressing home or end按 home 或 end 时从 getchar 获取大写 O
【发布时间】:2012-08-30 05:05:38
【问题描述】:

我在我的 C 代码中使用它:

system("stty -echo -icanon");

这是家庭作业的一部分,但这个特定部分是我正在做的超出作业要求的事情。

我们正在实现一个 shell,并且我们已经得到了一堆代码来开始。该代码不使用 ncurses(如果可以的话,我会使用它)并且更改它需要重写大量提供的代码。

当我按下我的 HOMEEND 键时,我得到一个大写 O(在 Open 中是一个 o),然后是 HOMEEND 键。我正在使用getchar() 来获取角色。

似乎只有这两个键可以做到这一点,但我不确定。如果提供的系统函数调用是唯一不同的东西,我不是 100%(我们也将 stdout 设置为非阻塞,但这不重要)。

我真的很困惑,我想实现 END 和 HOME 键,因为我经常使用它们。

如果这不是很多信息,我很抱歉。我对system 了解不多,无法真正理解-echo 和-icanon 对stty 的影响。我已经查看了手册页,但仍然无法弄清楚。

编辑

从 Alex Brown 的回答中,我确认我得到了转义字符。我有类似以下的内容(在错误的伪代码中):

while (TRUE) 
    ch = getchar()
    switch (ch)
        case HOME:
        case END:
            don't print anything...
            break

        default:
            printf(ch);
            break

所以它从转义序列中打印出 O,而不是 [(我有 0x48 用于 HOME0x46 用于 END)。仍然为如何获得真正的键码感到困惑......

【问题讨论】:

  • 在许多终端上,HOME 和 END 键发出转义序列而不是单个字符。
  • 既然你使用stty,你可能在一个类Unix系统上,它很可能是Linux,但你应该说因为你在做什么(处理)非常特定于系统。
  • @JonathanLeffler - 是的,我在 Linux 上运行 Bash。我的终端将 $TERM 报告为 xterm,但它实际上是 gnome 终端。

标签: c linux getchar


【解决方案1】:

对于控制台应用程序,HomeEnd 等键通常作为转义序列传输。确切的顺序取决于您使用的终端程序及其配置方式。信息通常存储在 termcap/terminfo 中,ncurses 根据您的终端类型从那里查找。

Gnome 终端发送:

  • ESC O H (0x1b 0x4f 0x48) 用于 Home
  • ESC O F (0x1b 0x4f 0x46) 用于 End

KDE Konsole 和 xterm 发送:

  • ESC [ H (0x1b 0x5b 0x48) 用于 Home
  • ESC [ F (0x1b 0x5b 0x46) for End

如果您读取 ESC 字符后跟 [O,则需要读取额外字符以确定哪个键被按下了。

【讨论】:

  • 接受这个答案,因为它提供了 Gnome/KDE 的示例。我没有意识到这一点。谢谢!我希望我可以使用 ncurses...
【解决方案2】:

终端(以及您的应用程序)接收许多元字符(例如箭头键、功能键和 home、end 等),作为转义字符 - 转义码后跟一个或多个字节值。由于每个字节都是由单独的 get char 调用接收的,因此这很可能是您所遇到的。我不知道您为什么将转义字符视为“O”。

【讨论】:

  • Hrm,这是有道理的。我可能会得到类似 [O.我注意到 [A 表示其中一个箭头键。您是否偶然知道区分 HOME 键和转义序列的方法?像获取键码而不是两个字符之类的东西?我想我可能需要做一些转义码处理......
  • 转义字符有时显示为[,转义字符后面的字节通常是可打印的(如 O)。听起来您已经找到了问题。
  • [ 前面可能有一个转义字符,您看到的是en.wikipedia.org/wiki/ANSI_escape_code
  • Home 键和它生成的字符序列之间没有区别——它没有一个唯一的字符代码。如果可以,您应该尝试使用 readline 库进行输入——它会为您处理这一切。
  • 有趣的@duskwuff,但是国际键盘是如何工作的?
猜你喜欢
  • 2013-02-26
  • 2014-06-11
  • 1970-01-01
  • 2014-10-06
  • 1970-01-01
  • 2016-02-16
  • 1970-01-01
  • 1970-01-01
  • 2022-01-15
相关资源
最近更新 更多