3

私は、コンソールからユーザー入力を取り込み、別のスレッドで出力するプログラムに取り組んでいます。ユーザーが何かを入力している途中で、printf が表示されてカーソル位置に表示されるような状況は避けたいと思います。

コンソール ウィンドウから c で非ブロック io を実行する方法はありますか? 理想的には、ユーザーが入力したものが画面に表示されないように、キープレスなどをキャプチャします。私は Ubuntu で開発を行っていますが、ncurses などを使用する必要がなければ最高です。

4

3 に答える 3

4

を使用termiosすると、端末のエコーを無効にできます。

#include <termios.h>

struct termios oflags, nflags;
tcgetattr(fileno(stdin), &oflags);
nflags = oflags;
nflags.c_lflag &= ~ECHO;
nflags.c_lflag |= ECHONL;

if (tcsetattr(fileno(stdin), TCSANOW, &nflags) != 0) {
    /* handle error */
}

次に、終了する前に (を使用atexit)、端末を復元する必要があります。

if (tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0) {
    /* handle error */
}
于 2009-08-14T04:37:38.913 に答える
2

HP フォーラムから直接取得した、C からのエコーをオフにする方法の例を次に示します(個人的にはテストしていません)。

これは、エコーをオフにする簡単な例です。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <termios.h>

#define STDIN_FDES 0

struct termios save;

int main(int argc, char *argv[])
{
int cc = 0;
char s_tmp[80],*p = NULL;
struct termios work;

cc = tcgetattr(STDIN_FDES,&save);
work = save;
work.c_lflag &= ~(ECHO);
cc = tcsetattr(STDIN_FDES,TCSANOW,&work);
(void) printf("\nEnter value: ");
(void) fflush(stdout);
p = fgets(s_tmp,sizeof(s_tmp),stdin);
if (p != NULL) (void) printf("Out -> %s\n",p);
cc = tcsetattr(STDIN_FDES,TCSANOW,&save);
return(cc);
}

注: SIGINT、SIGTERM などをキャッチし、元の termios を使用して端末をリセットするためのシグナル ハンドラーを用意することは非常に重要です。これは、最後の tcsetattr() が優先され、これが単にプロセスではなく端末デバイスに適用されるためです。エコーをオフにしてプロセスを終了すると、シェルでもオフになります。

それ以外の場合、Bash が適切なアプローチである場合は、どうやらstty -echo.

于 2009-08-14T04:31:51.840 に答える
0

あなたの質問を正しく理解していれば、エコーをオフにするか、非ブロッキング I/O を使用することは答えではありません。むしろ、バックグラウンド スレッドがユーザー入力スレッドを中断しないようにする必要がありますよね?

そのためには、ラインバッファ入力の代わりに生のキープレスにアクセスする必要があります。あなたが ncurses や同様のライブラリにアレルギーを持っている理由がわかりません。それが彼らの目的です!それがあなたのやり方なら、termiosまたはioctl呼び出しでそれを行うことができると思います....

しかし、マルチスレッド TTY 出力の問題を解決するには、次のようにします。

1) コンソールにアクセスできるユーザーを制御するミューテックスを作成する

バックグラウンド スレッドで、メッセージを出力するには:

ミューテックスを取得します。メッセージを書きます。ミューテックスを解放します。寝返って!

ユーザー入力スレッドで:

新しい入力が検出されたときにミューテックスを取得します。ユーザーが Enter キーを押すまで排他アクセスを保持し、ミューテックスを解放して、バックグラウンド スレッドに対話の機会を与えます。

それは役に立ちますか?

于 2009-08-14T05:35:20.967 に答える