6

抱歉标题太长了。我正在用 C 语言开发一个网络程序,它可以在标准输出上显示从网络接收到的消息,并通过 GNU readline 库在标准输入上接受用户输入。问题是,当用户通过 readline 在主线程上键入命令时,会收到一条网络消息并输出到 stdout,这将产生如下内容:

设想:

输入:1234567890
网络消息:Hello
当用户刚刚输入“7”时,网络消息到达

终端上的实际输出:

输入> 1234567
你好890_

有没有办法得到这样的输出?

你好
输入> 1234567890_

ps _ 是光标。

提前致谢!

4

4 回答 4

7

好的,我在四处搜索后找到了解决方案,并对 printf() 进行了以下替换。通过使用 rl_replace_line("", 0) 它将清除当前行并将光标放在行首,然后我可以打印一行消息,然后恢复 readline 提示,将原始行替换回原处,并且恢复光标位置。
但是,此 hack 需要对此 printf 函数的任何调用以在末尾包含一个 \n,否则该行将被 readline 覆盖。

#define printf(...) my_rl_printf(__VA_ARGS__)
void my_rl_printf(char *fmt, ...)
{
    int need_hack = (rl_readline_state & RL_STATE_READCMD) > 0;
    char *saved_line;
    int saved_point;
    if (need_hack)
    {
        saved_point = rl_point;
        saved_line = rl_copy_text(0, rl_end);
        rl_save_prompt();
        rl_replace_line("", 0);
        rl_redisplay();
    }

    va_list args;
    va_start(args, fmt);
    vprintf(fmt, args);
    va_end(args);

    if (need_hack)
    {
        rl_restore_prompt();
        rl_replace_line(saved_line, 0);
        rl_point = saved_point;
        rl_redisplay();
        free(saved_line);
    }
}
于 2011-02-21T20:25:33.443 回答
1

转储readline并读取每个char用户输入的内容。如果在用户输入时收到任何网络消息,请清除当前行,输出网络消息,然后重新打印用户当前输入的行。

这似乎是一项艰巨的工作,但这是我现在想到的唯一方法。

如果您确实转储readline,那么您可以使用curses它更容易...

于 2011-02-21T18:57:55.453 回答
0

您应该在这两个线程之间进行某种同步。互斥锁或从一个线程到另一个线程的标志,表明它正在处理标准输入或标准输出。

于 2011-02-21T17:18:46.417 回答
0

这可以使用curses(3)库来完成。

于 2011-02-21T18:31:50.050 回答