6

長いタイトルでごめんなさい。ネットワークから受信したメッセージをstdoutに表示し、GNU readlineライブラリを介してstdinでユーザー入力を受け入れるC言語のネットワークプログラムを開発しています。問題は、ユーザーが readline を介してメイン スレッドでコマンドを入力しているときに、ネットワーク メッセージが到着し、stdout に出力され、次のようなものが生成されることです。

シナリオ:

入力: 1234567890
ネットワーク メッセージ: こんにちは
ユーザーが「7」と入力すると、ネットワーク メッセージが届きます

端末の実際の出力:

入力> 1234567Hello
890_

このように出力する方法はありますか?

こんにちは
入力> 1234567890_

ps _ はカーソルです。

前もって感謝します!

4

4 に答える 4

7

OK 周りを検索した後、これに対する解決策を見つけ、次のように printf() を置き換えました。rl_replace_line("", 0) を使用すると、現在の行がクリアされ、カーソルが行の先頭に置かれます。次に、メッセージの行を出力し、readline プロンプトを復元して、元の行を元の場所に置き換えます。カーソル位置を復元します。
ただし、このハックでは、この 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

これらの 2 つのスレッド間である種の同期を行う必要があります。stdin または stdout で動作していることを示す、あるスレッドから別のスレッドへのミューテックス ロックまたは単なるフラグ。

于 2011-02-21T17:18:46.417 に答える
0

これは、 curses(3)ライブラリを使用して実行できます。

于 2011-02-21T18:31:50.050 に答える