【问题标题】:text auto complete using Tab in command line在命令行中使用 Tab 自动完成文本
【发布时间】:2015-09-13 10:56:43
【问题描述】:

我想知道如何用 C 语言实现一个程序,该程序可以自动完成您在命令行中输入的命令或文本。例如,假设您的程序正在提示用户输入文件名。大多数人会使用scanf() 或者这样做。然后在命令行用户会提示please input the file name:_

假设在同一目录中有一个shakespeare.txt。现在我输入了shakes,然后我希望计算机为我自动完成shakespeare.txt,就像大多数程序在用户点击Tab 时所做的那样。如何实现?

编辑:为了更清楚,再举个例子:

如果你在命令行中使用grep,比如grep -i "shakespeare" shakespeare.txt,在你自己完成shakespeare.txt之前,如果你只是使用Tab,就会出现一些候选人。

当我尝试在使用scanf() 之类的功能时提示用户输入时,如何实现我的程序以使其拥有此实用程序?

【问题讨论】:

  • 你能不能简单地捕获用户的tab并将当前输入字符串与当前工作目录中的内容以及可能的一组硬编码关键字进行比较?
  • 您是否对整个算法感兴趣,或者只是对如何在已经退出的方式上使用 tab 事件来自动完成某些事情感兴趣?

标签: c shell command-line autocomplete


【解决方案1】:

如果您考虑使用现有实用程序, 看看GNU readline library,它提供了一个非常简洁的实现你正在寻找的东西。
还有一些其他有用的功能,例如在输入中移动光标、提供输入历史记录和类似输入外壳的提示。

这个库的功能在不同的平台上是一样的。

正如来自维基百科的this example 所示,可以轻松设置指示完成的键:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <readline/readline.h>
#include <readline/history.h>

int main()
{
    char* input, shell_prompt[100];

    // Configure readline to auto-complete paths when the tab key is hit.
    rl_bind_key('\t', rl_complete);

    for(;;) {
        // Create prompt string from user name and current working directory.
        snprintf(shell_prompt, sizeof(shell_prompt), "%s:%s $ ", getenv("USER"), getcwd(NULL, 1024));

        // Display prompt and read input (NB: input must be freed after use)...
        input = readline(shell_prompt);

        // Check for EOF.
        if (!input)
            break;

        // Add input to history.
        add_history(input);

        // Do stuff...

        // Free input.
        free(input);
    }
    return 0;
}

【讨论】:

    【解决方案2】:

    不清楚你的要求是否由

    1. 程序本身在运行时。大概你会实现一些自定义命令行。
    2. 启动程序之前的操作系统命令行(例如 bash)并且您只想自动完成传递给它的参数

    您的 grep 示例建议您询问有关 shell 完成的问题。 Here 就是一个例子。

    【讨论】:

      【解决方案3】:

      因为在 C 语言中没有可移植的解决方案,可以在不按 Enter 的情况下了解您在提示中键入的内容,您需要逐个字符地阅读。

      • 在 Windows 中,您可以使用 _getch() 函数读取一个字符,而无需按 Enter。该函数在conio.h中定义
      • 在 linux 中可以使用 getch() 函数。

      注意:您可能需要使用 getche() 来回显字符。

      您将需要定义一个缓冲区,您将逐个字符地存储用户按下的所有内容,直到用户按下回车键或按下回车键。当您找到 \t 时,您将分析缓冲区中的内容并据此做出决定。

      以下代码是一个过于简化的示例:

      char c;
      int i = 0;
      
       do {
           c = _getche();
               if (c == '\t') {
                   // Autocomplete
                   // Print the rest of the word here
               }
          else {
              buff[i++] = c;
          }
      
       } while (c != '\n' && c!='\r');
       buff[i] = '\0'; // Let's keep the standard
      

      【讨论】:

        猜你喜欢
        • 2010-12-22
        • 2021-05-08
        • 2018-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多