【问题标题】:Scan all characters entered until see a tab char扫描所有输入的字符,直到看到一个制表符
【发布时间】:2017-09-02 22:13:27
【问题描述】:

我想在命令行应用程序上自动完成,但就像在 bash 中一样,您可以使用 tab 键来完成命令。但是 getchar() 似乎要等到收到换行符后才开始读取任何字符。

scanf 似乎以同样的方式工作。

有什么方法可以一次扫描一个字符,无论它们是空白字符还是控制字符?

我希望能够在输入构建命令时逐个字符地读取字符,然后在收到选项卡字符后,我将尝试在我的应用程序中查找如何完成和打印完整命令。

【问题讨论】:

  • 看过其他 C 程序是如何做到这一点的?从工作代码中复制通常是个好主意;这就是 FOSS 的意义所在(而 bash,例如 FOSS,但我认为 bash 在其自动补全方面有点难以理解)
  • 如果你真的不能使用别人的作品,你就必须调整终端属性来使用'non-canonical'模式。在规范模式下,在用户点击返回(或使用 control-D (EOF) 键)之前,不会向程序发送任何输入。请参阅Canonical vs non-canonical terminal input 了解更多信息。而且您必须确保在程序退出之前恢复终端属性 - 并且可能在您的命令行应用程序也运行任何其他程序时。这都是艰苦的工作;用别人的努力代替。
  • 这个问题不是 *nix 特有的,MSVC 有自己的getch_getch,在每次按键时都会返回(尽管您应该检查按下非键入键时会发生什么,例如 PageUp)。您可以在提交阻塞函数之前使用kbhit_kbhit 进行轮询。
  • 你可以看看Tab completion feature in Unix shell development,但那里的答案不如这里的好(他们只列出了 GNU Readline)。

标签: c command-line


【解决方案1】:

不要重新发明轮子。

使用其他项目构建命令行的方式:为您实现该工作的库。

许多 CLI 提示依赖于 GNU readline,我认为这很好,如果有点混乱和沉重。另外,它是 GPL,所以取决于您是否喜欢。

我会调查linenoise。它非常轻量级,如果您决定真的想要自己实现用户界面而不是包含一两个文件,好吧,这样做,但看看看起来相当简洁的参考实现。警告:到目前为止,我自己还没有使用过。不过,API 非常简单,可以在他们的example 中看到。

一个流行的替代方案是libedit/editline

【讨论】:

    【解决方案2】:

    您需要GNU Readline Library。每当用户按下一个键('\t',在您的情况下)时,使用 rl_bind_key() 函数添加文件名完成处理函数。

    如果您尝试推出自己的 readline 样式功能,您将陷入痛苦的世界。

    (If you are on Windows.)

    【讨论】:

    • @ChronoKitsune ha,刚刚写的一样,只是在你之后几秒钟。但是请看我的回答; libedit 不是唯一的 BSD 竞争对手。
    猜你喜欢
    • 2015-08-04
    • 2013-08-14
    • 2016-03-24
    • 1970-01-01
    • 2016-06-20
    • 1970-01-01
    • 1970-01-01
    • 2016-07-02
    • 2020-09-07
    相关资源
    最近更新 更多