ncursesを入門してみました、これはそのメモ書きです。
この記事のメインはスクリーンの移動です。
ncurses全体の情報を知りたい方はページ一番下の参考記事を参照ください。
目次
ncursesとは
ncursesの概要です。とにかく使用例が見たいという方は読み飛ばしてください。
みなさんncursesをご存知でしょうか。
ncursesライブラリを使うと画面をスクリーンとウィンドウという単位で簡単に操作することができます。
Vimや less, zsh, MySQLなど様々なプログラムがncursesに依存しています。
実は端末ごとに画面制御の方法が異なります、また画面制御系の命令は直感的には理解しにくいです。
そこで、ncursesを使用することで端末が違っても同じように操作することができます。
要するに面倒な画面制御の処理を代わりに行ってくれます。
ncursesの名前の由来についてですが、cursesライブラリの後継機なのでnew cursesを略してncursesになったようです。curses自体はすでに開発終了となっています。
ncursesの基本
端末の初期化
ncursesを使用する場合、まず初めに行うのは端末の初期化です。
また、プログラム終了時には生成した端末を削除する必要があります。
コードinit_screen.cに例を示します。
// init_screen.c #include <ncurses.h> int main(void) { initscr(); //端末の初期化 endwin(); //端末の終了 return 0; }
文字/文字列の出力
文字/文字列を出力します。とりあえず”Hello, world!”を表示させます。
// print_str.c #include <ncurses.h> int main(void) { initscr(); /* 参考ページ * http://invisible-island.net/ncurses/man/curs_addstr.3x.html */ addstr("Hello, world\n"); //現在の端末へ文字列を出力する // -> Hello, world! addnstr("Hello, world\n", 8); //現在の端末へ文字列の先頭からをn文字までを出力する // -> Hello, w getch(); //キー入力があるまで待機 endwin(); return 0; }
実行結果
Hello, world! Hello, w
スクリーンの移動
上記の他にもmoveでカーソルを移動させたり、ウィンドウを作成したりできるのですが、ここではスクリーンを複数作成しそれぞれのスクリーン間を移動してみます。
大まかな流れ
- newtermで複数の端末を作成
- set_termで端末を切り替え
- endwinで終了
1.newtermで複数の端末を作成
newtermにより複数のスクリーンを作成します。返り値は SCREEN* 型ですのでSCREEN*型の配列に格納していきます。
#include <ncurses.h> SCREEN *scr[5]; int main(void) { // SCREEN* newterm("ターミナルの種類", 入力デバイス, 出力デバイス) scr[0] = newterm("xterm", stdout, stdin); /* 別の端末(スクリーン)を生成する前に endwin() を呼び出す必要がある。 * endwin() を呼び出したからといってメモリは解放されない。 */ endwin(); scr[1] = newterm("xterm", stdout, stdin); endwin(); scr[2] = newterm("xterm", stdout, stdin); endwin(); scr[3] = newterm("xterm", stdout, stdin); endwin(); scr[4] = newterm("xterm", stdout, stdin); endwin(); }
2.set_termで端末を切り替え
申し訳ありません執筆途中です。
まとめ
// multi_screen.c #include <ncurses.h> #define COUNT_SCREEN 5 SCREEN *scr[COUNT_SCREEN]; void scr_foreach(void (*func)(int)) { int i; for (i = 0; i < COUNT_SCREEN; i++) func(i); } void init(int i) { scr[i] = newterm("xterm", stdout, stdin); cbreak(); noecho(); endwin(); } void end() { endwin(); } int main(int argc, char *argv[]) { int c, num; scr_foreach(init); set_term(scr[0]); refresh(); while ((c = getch()) != '\x1b') { num = c - '0'; if (num >= 1 && num <= COUNT_SCREEN) { endwin(); set_term(scr[num - 1]); refresh(); } else { echochar(c); } } end(); return 0; }
参考記事
Announcing ncurses 6.0 [https://www.gnu.org/software/ncurses/]
NCURSES – New Curses [http://invisible-island.net/ncurses/]
Python で Curses プログラミング [http://docs.python.jp/2/howto/curses.html]
Curses ライブラリー – IBM [http://www.ibm.com/support/knowledgecenter/ssw_aix_61/com.ibm.aix.genprogc/curses.htm?lang=ja]
lf233, SoftwareDevelopment: Ncurses 入門 [http://linuxmag.osdn.jp/Japanese/March2002/article233.shtml]
C言語によるオリジナルゲームの開発 [http://www.kushiro-ct.ac.jp/yanagawa/ex/2-game/index.html]
“せりか式 – マニュアル – ncurses” [http://www.kis-lab.com/serikashiki/man/ncurses.html]