5

私が構築しているプログラムは、switch ケースを含む無限 while ループで実行されます。ケースごとにwhileループを挿入し、ループ内でいくつかの操作を実行したいのですが、キーボード入力が与えられるとすぐにループを終了する必要があります。そのため、キーボードから入力を取得した後、ネストされた while ループを使用して別のケースが実行され、プロセスが続行されます。

構造は次のとおりです。

while()//infinite loop
    {
    ...............      //operations
    ...............      //operations
    switch()
        {
        case 1:
        ...............    //operations
        ...............    //operations
        while()//infinite loop
             {
             ..............
             ..............
             exit if there is any input from keyboard
             }
        break;

        case 2:
        ...............    //operations
        ...............    //operations
        while()//infinite loop
             {
             ..............
             ..............
             exit if there is any input from keyboard
             }
        break;


        case n:
        ...............    //operations
        ...............    //operations
        while()//infinite loop
             {
             ..............
             ..............
             exit if there is any input from keyboard
             }
        break;
        }
  }

何か方法はありますか???

4

3 に答える 3

6

Linux キーボード入力はバッファリングされます。その場で打たれたキーをキャッチするには、TERM IO を設定する必要があります。

main()の先頭付近に呼び出しを追加します (以下のコードを参照) 。

term_nonblocking();

キャリッジ リターン (CR) を待たずに、オンザフライで押されたキーを読み取ります。

コード:

struct termios stdin_orig;  // Structure to save parameters

void term_reset() {
        tcsetattr(STDIN_FILENO,TCSANOW,&stdin_orig);
        tcsetattr(STDIN_FILENO,TCSAFLUSH,&stdin_orig);
}

void term_nonblocking() {
        struct termios newt;
        tcgetattr(STDIN_FILENO, &stdin_orig);
        fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK); // non-blocking
        newt = stdin_orig;
        newt.c_lflag &= ~(ICANON | ECHO);
        tcsetattr(STDIN_FILENO, TCSANOW, &newt);

        atexit(term_reset);
}

注:term_reset()プログラムが終了すると、(端末パラメータをリセットするために) 自動的に呼び出されます。

getchar()キーの押下を検出するために、プログラムのどこでもノンブロッキングを呼び出すことができます

int i = getchar();

キーが押されたかどうかを確認します。

if (i > 0) {
    // key was pressed, code in `i`
}

たとえば、あなたのプログラムでは:

int key = 0;

while (... && key <= 0) {
   // ... 
   key = getchar();
}

注:出力をバッファリングしない場合は、呼び出しますsetbuf(stdout, NULL);

(@stacey からのコメント: getchar()は、利用可能なキーがない場合に 0 または -1 を返す場合があります)

于 2013-06-05T11:09:26.700 に答える
0

ありがとうございます....私の答えは少し箱から外れていますが、ring0のアプローチの方がはるかに優れていると思います。これが私がしたことです。

  • 外側の while ループ内にコードを追加して、コンパイラがファイル (data.dat など) からスイッチ ケースの引数を取得できるようにします。
  • ネストされた while ループのそれぞれに同様のコードを追加して、data.dat から取得した変数がループの実行に必要なものである場合は続行し、そうでない場合は中断します。
  • Linux ではバックグラウンドでプロセスを実行できるので、メイン プログラムをバックグラウンドで実行し、それに応じて data.dat を編集しました。

この方法は私にとってはうまくいっていますが、必ず ring0 の方法も試してみます。

于 2013-06-06T07:48:46.320 に答える