【问题标题】:readline with a default value具有默认值的 readline
【发布时间】:2015-10-26 11:05:35
【问题描述】:

我可以使用 GNU readline 将用户输入限制为 5 个字符:

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

static int limit_rl(FILE *f)
{
    if (rl_end > 5) {
        return '\b';
    }
    return rl_getc(f);
}

int main(void)
{
    char *str;

    rl_getc_function = limit_rl;
    str = readline("> ");
    printf("%s\n", str);
    free(str);
    return 0;
}

但是,如何读取具有默认值(不是提示)的输入,例如:

> ummy
  ^ cursor here

如果用户键入 dEnter 返回“dummy”

如果用户键入 DELEnter 返回“mmy”

【问题讨论】:

  • 你的意思是ummy应该已经存在了?
  • 查看rl 示例 - 可以设置一个启动挂钩 (rl_startup_hook),它执行一次 rl_insert_text,然后自行禁用。
  • @Jongware,就像一个魅力:code,谢谢一百万!!
  • @Jongware,您的评论似乎是对我的回答,发表您的评论作为答案,我会接受。
  • @Magisch:它在文档中:“readline 返回的行分配有malloc();,调用者应该在完成后free() 行。”

标签: c readline


【解决方案1】:

readline的主页上提到了一个可能的用途:

rl.c 是一个示例程序,它使用 Readline 读取用户输入的一行并将其回显到标准输出,适用于 shell 脚本。

由于编辑现有条目很可能是其中的一部分,因此我决定查看其来源 (direct download link)。这确实显示了如何通过使用 hook 函数将字符串插入到readline 出现在屏幕上之前使用的缓冲区中:

变量:rl_hook_func_t * rl_startup_hook

如果非零,这是在readline 打印第一个提示之前要调用的函数的地址。
(https://cnswww.cns.cwru.edu/php/chet/readline/readline.html#IDX223)

在钩子函数中你可以直接操作内部缓冲区,例如插入文本:

函数:int rl_insert_text (const char *text)

文本插入到当前光标位置的行中。返回插入的字符数。
(https://cnswww.cns.cwru.edu/php/chet/readline/readline.html#IDX295)

钩子函数只需要执行一次(每个readlinereadline_internal_setup 内调用它只调用一次),但显然 rl 的作者采用了皮带和吊带方法,并在它被禁用后专门禁用它用过。

来自rl.c的相关sn-ps,cmets是我的:

/* a global char * to hold a default initial text */
static char *deftext;

/* the callback function. The argument is supposed to be 'void' per
   its declaration:
       typedef int rl_hook_func_t (void);
   so you cannot provide the default text here */
static int set_deftext ()
{
  if (deftext)
    {
      /* Apparently the "current cursor position" in which text is inserted
         is 0, when initially called */
      rl_insert_text (deftext);
      deftext = (char *)NULL;

      /* disable the global 'rl_startup_hook' function by setting it to NULL */
      rl_startup_hook = (rl_hook_func_t *)NULL;
    }
  return 0;
}

// ...
if (deftext && *deftext)
   rl_startup_hook = set_deftext;

temp = readline (prompt);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-24
    • 1970-01-01
    • 1970-01-01
    • 2022-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-12
    相关资源
    最近更新 更多