代码之家  ›  专栏  ›  技术社区  ›  Jack

用stdin识别箭头键

  •  10
  • Jack  · 技术社区  · 15 年前

    在C或OCaml程序中,是否可以使用跨平台的方法来处理退格键和箭头键?

    我要实现的是捕捉箭头键来覆盖shell中的行为(通过重新设置最后一行或类似的操作)。我认为这件事落在实际程序之前,它不是由代码本身处理的,所以我不知道这是否可能。

    这个程序是在Linux、OSX和Windows上编译的(在cygwin上),所以我想在所有平台上都这样做。。

    4 回复  |  直到 15 年前
        1
  •  9
  •   Leandros    6 年前

    我最近也做过类似的事情(尽管我的代码仅限Linux)。必须将stdin设置为非规范模式才能读取按箭头键的次数。这应该可以在OSX和Linux上运行,也可能在Cygwin上运行,尽管我不能肯定。

    open Unix
    let terminfo = tcgetattr stdin in
      let newterminfo = {terminfo with c_icanon = false; c_vmin = 0; c_vtime = 0} in
        at_exit (fun _ -> tcsetattr stdin TCSAFLUSH terminfo); (* reset stdin when you quit*)
        tcsetattr stdin TCSAFLUSH newterminfo;
    

    您可能还想设置 c_echo 如果设置为false,则箭头键将被打印到终端(但随后您将不得不手动打印其他所有内容)。

    大多数终端表示使用 ANSI escape sequences cat 如果没有参数并开始按箭头键,则可以看到使用的转义序列。它们通常是

    up - "\033[A"
    down - "\033[B"
    left - "\033[D"
    right - "\033[C"
    

    其中'\033'是 esc

        2
  •  5
  •   Ignacio Vazquez-Abrams    15 年前

        3
  •  2
  •   Gilles 'SO- stop being evil'    15 年前

    支持可打印字符行以外的键盘输入的标准方法是通过 ncurses 图书馆,有一个 Ocaml binding readline

    如果您所做的只是逐行阅读输入,但希望您的用户有一个像样的行编辑器,则不需要在程序中包含任何支持。相反,只要告诉用户使用包装程序,比如 rlwrap (基于readline)或 ledit . 这些包装器确实提供了行编辑和历史记录,这两个特性是您作为需求列出的。我建议您只有在需要一些更新奇的东西时才在程序中构建输入处理,例如当用户按 .

        4
  •  0
  •   Clifford    15 年前

    '\b' 是退格字符。

    推荐文章