【问题标题】:Tab Completion and Partial Completion制表符补全和部分补全
【发布时间】:2018-06-15 21:24:42
【问题描述】:

我想制作一个程序,它以类似于 Linux 上的ip 的方式接受命令。例如,我想要一个完整的命令show interface options,但用户可以只输入show in options,如果它们与其他命令不冲突,甚至可以只输入s i o

我对如何解决这个问题有一些想法,我想在 C 中执行此操作。所以问题是什么是解决此问题的好方法,同时在 Linux/UNIX 系统之间保持尽可能的可移植性。

我的第一个想法是有一个链表。每个列表项指向字符串数组中的下一个命令,最后一个命令具有函数调用的地址(请原谅我草率的伪代码)。

header.h

typedef int8_t (__cdecl *proc_stub)(void *data, uint16_t len);
typedef struct s_proc_stub
{
    char command[16];
    proc_stub proc;
    struct s_proc_stub *next;
};
struct s_proc_stub proc_list[] =
{
    { "cmd", CommandFunction, ... },
    { "set", SetFunction, ... },
    ...
};

我觉得其中一个缺点可能是额外的 CPU 和 RAM 使用率。它也可能容易出错,从而导致漏洞。这个过程是面向互联网的,所以我想保证代码的安全。

我的下一个想法是使用 strtok() 并对每个令牌执行 strnicmp() 。另一种选择是使用指针算法更快地模拟 strtok() 并且不修改缓冲区。我觉得 strtok 是最直接的方法并且最不容易出错,但我想说我记得 strtok() 与其他两种方法相比有一些额外的开销。

目标平台是 Raspberry Pi,它只有大约 2GB 的 RAM 可供使用。驱动器通常很小,CPU 还可以,但不适合繁重的处理。我预计这些进程会因命令处理而承受重负载,因此我想要一个理想的解决方案,以最大限度地减少 RAM 和 CPU 使用量。我很想听听一些我不知道的方法! :)

【问题讨论】:

  • strnicmp 并非始终可用。 Posix 函数是strcasecmp,在 glibc 中可用。这些函数可能支持或不支持区域设置,但支持区域设置的版本将比strtok 产生更多开销,fwiw。
  • @rici 是的,谢谢,我在 C 中找到了一个实现并对其进行了修改以供我使用。 :) stackoverflow.com/questions/30733786/…
  • 您链接的问题中的实现不适用于 UTF-8 编码的字符串,并且如果您的语言环境设置正确(并且它是一个 ISO-8859-x 语言环境,我认为这在当今非常罕见。)如果你只比较普通的 ascii,这很好但过度。

标签: c parsing console


【解决方案1】:

我认为 trie(前缀树)数据结构是合适的,https://en.wikipedia.org/wiki/Trie;具体来说,最小化内存量,人们可能更喜欢紧凑的前缀树,(基数树)。来自https://en.wikipedia.org/wiki/Radix_tree

在一个 trie 中,所有的比较都需要固定的时间,但是查找一个长度为 m 的字符串需要 m 次比较。基数树可以通过更少的比较来执行这些操作,并且需要更少的节点。

这是一个实现,https://stackoverflow.com/a/31718868/2472827

【讨论】:

  • 是的,这很完美!基本上是我在想的,但这似乎在方法和实现中得到了更好的定义。谢谢你提供的详情! :)
【解决方案2】:

我不知道这是否有用,但如果您不想重新发明轮子,请查看GNU readline,这是 GNU/Linux 中用于此类东西的库。

【讨论】:

  • 我更愿意在我自己的程序中维护代码而不使用外部库,但我会牢记该方法。 :)
猜你喜欢
  • 1970-01-01
  • 2011-03-18
  • 1970-01-01
  • 2011-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-16
  • 1970-01-01
相关资源
最近更新 更多