3

矢印キーの押下に応答するコードの簡単な小さなスニペットを作成しようとしています。up が ^[[A で表されることはわかっており、そのシーケンスをチェックする次のコードがあります。

     while( 1 )
     {
         input_char = fgetc( stdin );

         if( input_char == EOF || input_char == '\n' )
         {
             break;
         }

         /* Escape sequence */
         if( input_char == 27 )
         {
             input_char = getc( stdin );

             if( input_char == '[' )
             {
                 switch( getc( stdin ) )
                 {
                     case 'A':
                     printf("Move up\n");
                     break;
                 }
             }
         }
     }

「上へ」を押すたびに、エスケープ シーケンス (^[[A) が画面に表示されますが、Enter キーを押すまで「上へ移動」は表示されません。

最終的な目標は、現在の行のテキストを他のデータに置き換えることです。

printf("\r%s", "New Text");

「上に移動」の代わりに、Enter キーを押すまで表示されません。

文字の読み方がおかしいのでしょうか?

ありがとう!

EDITクイックノート、* nixシステム用です。

解決策 皆さん、ご指摘ありがとうございます。私は stepanbujnak のソリューションを採用しました。私が気づいたことの 1 つは、文字列を変更するキー (バックスペースなど) の多くの動作が、予想とは異なることです。それはライン上の何でも(printf'dのものを含む)バックスペースします、そして私はそれを説明しなければなりませんでした。その後、残りを一列に並べるのはそれほど悪くはありませんでした:)

4

3 に答える 3

4

実際には、 termiosを使用して行バッファリングを無効にするだけで済みます

これを行う例を次に示します。

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

int main() {
  struct termios old_term, new_term;
  char c;

  /* Get old terminal settings for further restoration */
  tcgetattr(0, &old_term);

  /* Copy the settings to the new value */
  new_term = old_term;

  /* Disable echo of the character and line buffering */
  new_term.c_lflag &= (~ICANON & ~ECHO);
  /* Set new settings to the terminal */
  tcsetattr(0, TCSANOW, &new_term);

  while ((c = getchar()) != 'q') {
    printf("You pressed: %c\n", c);
  }

  /* Restore old settings */
  tcsetattr(0, TCSANOW, &old_term);

  return 0;
}
于 2012-04-19T13:45:35.103 に答える
1

curses矢印キーなどのエスケープ シーケンスをキャプチャするためのライブラリを参照してください。

http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/keys.html

ほとんどのシステムでは、矢印キー、ホーム、ページアップ、ブレークなどのキーはエスケープ キーであり、エスケープ シーケンスを使用して識別します。0x1B + シーケンスのようなものです。生でキャプチャしたい場合は、ファイル記述子から直接入力を読み取り、シーケンスをリッスンする必要があります。代替手段は、上記の ncurses を使用することです。

curses を使用する以外に、次のようなシステム コールを使用してこれを達成する方法を以下に示します。read

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
    int fd = 0x0; /* STDIN */
    size_t bytes_read;
    char buf[12];

    bytes_read = read(fd, buf, 3);
    printf("%02x %02x %02x\n", buf[0], buf[1], buf[2]);
    return 0;
}

UPを押した後の出力

Lukes-ASA-Macbook:tmp luke$ gcc -o out test.c
Lukes-ASA-Macbook:tmp luke$ ./out
^[[A
1b 5b 41

これであなたの道が開けるはずです。

探している入力をバッファリングして0x1bから、解析フラグを有効にして、単一文字の解析の代わりに文字のエスケープ シーケンスを探すことができます。

于 2012-04-19T13:29:40.857 に答える