- ベストアンサー
テキストカーソル位置の取得
C言語でテキストカーソル位置の取得をしたいのですがどうしたらよいでしょうか? printf("\x1B[6n\n); で ^[[24;9R のようにカーソル位置を表示できることまではわかったのですが、 これをどう加工して、変数に取得できるでしょうか? sprintf?,scanf? よろしくお願いします。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
エスケープ・シーケンスはコンソールデバイス(画面出力/キー入力デバイス)が処理していますので、printf() つまり stdout に出力しないと動作しません。 また、stdout に "\x1B[6n" を出力すると、コンソールデバイスは現在のカーソル位置を stdin に "\x1B[yy;xxR" の形式で返しますから、結果は当然 stdin から読まなければなりません。 sprintf(buff, ...) で buff にエスケープ文字列を書き込んでも、コンソールデバイスには何の指令も届きませんから、printf(...), fprintf(stdout, ...), puts() など stdout に出力する関数を使用してください。 結果の文字列を受け取る場合も同様です。gets() など stdin から入力する関数を使います。 sscanf(buff, ...) を使うのでしたら、buff にはコンソールデバイスから返される文字列が事前にセットされいなければなりません。 #include <stdio.h> void main(void) { char buff[16]; int cursor_x, cursor_y; printf("%s", "\x1B[6n"); gets(buff); sscanf(buff, "\x1B[%d;%dR", &cursor_y, &cursor_x); printf("x = %d, y = %d\n", cursor_x, cursor_y); } もっと簡単にするのなら buff を使わずに直接 stdin から読み込みます。 #include <stdio.h> void main(void) { int cursor_x, cursor_y; printf("%s", "\x1B[6n"); scanf("\x1B[%d;%dR", &cursor_y, &cursor_x); printf("x = %d, y = %d\n", cursor_x, cursor_y); } 確かに No.1 のものは、説明のためとはいえ冗長過ぎましたね。
その他の回答 (1)
- route156
- ベストアンサー率85% (93/109)
エスケープ・シーケンスですね。例えば次のようになると思います。 #include <stdio.h> #include <stdlib.h> #include <string.h> void main(void) { char buff[16]; int cursor_x, cursor_y; printf("%s", "\x1B[6n"); gets(buff); cursor_y = atoi(strchr(buff, '[') + 1); cursor_x = atoi(strchr(buff, ';') + 1); printf("x = %d, y = %d\n", cursor_x, cursor_y); } ※ 左上隅の座標は 0, 0 ではなくて 1, 1 になります。 ※ サンプルを走らせると x は必ず 1 になりますが、これはコマンドとして実行したためです。(実行のために Enter キーを押すと、カーソルは左端に移動しますから) ※ Borland C でしたら、#include <conio.h> で int wherex(void) と int wherey(void) が使えるはずですので、そちらの方が簡単でしょう。(MS-DOS の場合ですが)
お礼
こんにちは。ご回答ありがとうございます! 実際に動かしてみましたが、いや~、お見事ですね。 しっかりと動きました。採用させてもらいます。 ありがとうございました。 さて、私の考えていたアプローチでもやってみたんですが、 どうもうまくいきませんでした。 x = 0, y = 0 となってしまいます。 どなたか原因わかる方いらっしゃらないでしょうか? よろしくお願いします。 -- #include <stdio.h> void main(void) { char buff[16]; int cursor_x, cursor_y; sprintf(buff, "%s", "\033[6n"); sscanf(buff, "[%[^;];%[^R]R", &cursor_y, &cursor_x); printf("x = %d, y = %d\n", cursor_x, cursor_y); }
お礼
そっか、画面に出力しないと行けないのですね。納得しました。 コードの方もお見事ですね! 使わせていただきます。m(__)m 余計なゴミを出力しないといけないと思ったんですが、 エスケープシーケンスでうまく消せばいんですね! やってみます! 助かりました。ありがとうございます!