Copy

MIDORIAck ソフトウェア材料の倉庫

Contents ♪

ncurses 〜CUIプログラム
ncursesは、ターミナル制御で使われているDEC社VT100のエスケープコードをC言語関数に抽象化したライブラリです。歴史のあるライブラリですが、現在でも主なLinux/UNIX環境のターミナル上で動くのCUIプログラムで広く使われております。
ncursesには、前身であるcursesライブラリからの引き継ぎを含めた大量の関数が存在します。ここでは、ncursesを使ったCUIプログラムを作成するために必要な基本的な関数を選んで並べております。
こちら(本家サイト)に説明付きの記事があります。あわせてご参照ください。
ncurses(tenkaiken.com)
2025.01.28
日本語用のncurses
マルチバイト文字環境を考慮したncursesHello World
#include <ncurses.h>
#include <locale.h>

int main()
{
    setlocale(LC_ALL, "");      // ロケール:""の場合は環境変数LANGが適用される
    initscr();
    printw("こんちは");
    refresh();
    getch();
    endwin();
    return 0;
}
日本語を使うならば、libcursesではなくlibcurseswをリンクしてNCURSES_WIDECHARを定義した方がよい。
gcc xxx.c -DNCURSES_WIDECHAR -lncursesw -o xxx 
2025.01.28
スクリーンサイズサイズ取得 getmaxyx
getmaxyx()は、yとxに引数戻り値として画面サイズを返す。
getmaxyx(WINDOW *win, int y, int x);
#include <ncurses.h>

int main()
{
    int x, y;

    initscr();
    getmaxyx(stdscr, y, x);
    printw("y=%d x=%d", y, x);
    getch();
    endwin();
    return 0;
}

スクリーンサイズを保持する変数

グローバル変数のLINES・COLSは、ウィンドウの行数と桁数を保持する。
これらはスクリーンサイズの変化に追従して値が更新される。
#include <ncurses.h>

int main()
{
    int x, y;

    initscr();
    while (getch() != 'q') {
        printw("(%3d %3d)\n", LINES, COLS);
        refresh();
    }
    endwin();
    return 0;
}
2025.01.28
カーソル移動 move
move()はカーソルを、指定する座標へ移動させる。
int move(int y, int x);
#include <ncurses.h>

int main()
{
    initscr();
    move(0, 0);
    printw("MOVE0_0");
    move(2, 2);
    printw("MOVE2_2");
    refresh();
    getch();
    endwin();
    return 0;
}
ncursesでの座標は(行, カラム)であり、即ち(y, x)である。
行、カラムともに始点は0とする。画面左上(ホーム)は(0, 0)である。
2025.01.28
カーソル非表示 curs_set
curs_set()は、カーソルの非表示・表示を設定する。
引数に0を指定すると非表示、1で表示。
int curs_set(int visibility);
#include <ncurses.h>

int main()
{
    initscr();
    curs_set(0);    //カーソルを非表示
    printw("EraseCursor");
    refresh();
    getch();
    endwin();
    return 0;
}
2025.01.28
文字列出力 addstr
addstr()は文字列を現在のカーソル位置に追加する。
int addstr(char *str);
#include <ncurses.h>
#include <locale.h>

int main()
{
    setlocale(LC_ALL, "");
    initscr();
    move(0, 0);
    addstr("ABCあいう");
    refresh();
    getch();
    endwin();
    return 0;
}

日本語出力 addwstr

addwstr()はワイド文字(wchar_t型)の文字列を現在のカーソル位置に追加する。
int addwstr(wchar_t *wstr);
#include <ncurses.h>
#include <locale.h>
#include <wchar.h>

int main()
{
    wchar_t wc[10];
    int i;
    setlocale(LC_ALL, "");      //// ""の場合は環境変数LANGが適用される
    initscr();
    move(0, 0);
    addwstr(L"ABCあいう");
    refresh();
    for (i = 0; i < 5 ; i++) {
        wc[i] = 0x3042 + i * 2;
    }
    wc[i] = L'\0';
    move(1, 0);
    addwstr(wc);
    refresh();
    getch();
    endwin();
    return 0;
}
ABCあいう
あいうえお
2025.01.28
可変長引数 vw_printw
vw_printw()は標準ライブラリのvprintf()のncurses版である。
#include <ncurses.h>
#include <stdarg.h>

int vashow(const char *fmt, ...)
{
    va_list va;
    va_start(va, fmt);
    vw_printw(stdscr, fmt, va);
    va_end(va);
}

int main()
{
    initscr();
    vashow("%d %s", 100, "ABCDEFG");
    refresh();
    getch();
    endwin();
    return 0;
}
2025.01.28
特殊文字定数
罫線や記号などの特殊な文字のいくつかは、次のように定数で定義されている。
#include <ncurses.h>

int main(int argc, char *argv[])
{
    initscr();

    printw("Upper left corner           "); addch(ACS_ULCORNER); printw("\n");  // ┌
    printw("Lower left corner           "); addch(ACS_LLCORNER); printw("\n");  // └
    printw("Lower right corner          "); addch(ACS_LRCORNER); printw("\n");  // ┘
    printw("Tee pointing right          "); addch(ACS_LTEE); printw("\n");      // ├
    printw("Tee pointing left           "); addch(ACS_RTEE); printw("\n");      // ┤
    printw("Tee pointing up             "); addch(ACS_BTEE); printw("\n");      // ┴
    printw("Tee pointing down           "); addch(ACS_TTEE); printw("\n");      // ┬
    printw("Horizontal line             "); addch(ACS_HLINE); printw("\n");     // ─
    printw("Vertical line               "); addch(ACS_VLINE); printw("\n");     // │
    printw("Large Plus or cross over    "); addch(ACS_PLUS); printw("\n");      // ┼
    printw("Scan Line 1                 "); addch(ACS_S1); printw("\n");        // ⎺
    printw("Scan Line 3                 "); addch(ACS_S3); printw("\n");        // ⎻
    printw("Scan Line 7                 "); addch(ACS_S7); printw("\n");        // ⎼
    printw("Scan Line 9                 "); addch(ACS_S9); printw("\n");        // ⎽
    printw("Diamond                     "); addch(ACS_DIAMOND); printw("\n");   // ◆
    printw("Checker board (stipple)     "); addch(ACS_CKBOARD); printw("\n");   // ▒
    printw("Degree Symbol               "); addch(ACS_DEGREE); printw("\n");    // °
    printw("Plus/Minus Symbol           "); addch(ACS_PLMINUS); printw("\n");   // ±
    printw("Bullet                      "); addch(ACS_BULLET); printw("\n");    // ·
    printw("Arrow Pointing Left         "); addch(ACS_LARROW); printw("\n");    // <
    printw("Arrow Pointing Right        "); addch(ACS_RARROW); printw("\n");    // >
    printw("Arrow Pointing Down         "); addch(ACS_DARROW); printw("\n");    // v
    printw("Arrow Pointing Up           "); addch(ACS_UARROW); printw("\n");    // ^
    printw("Board of squares            "); addch(ACS_BOARD); printw("\n");     // #
    printw("Lantern Symbol              "); addch(ACS_LANTERN); printw("\n");   // ␋
    printw("Solid Square Block          "); addch(ACS_BLOCK); printw("\n");     // #
    printw("Less/Equal sign             "); addch(ACS_LEQUAL); printw("\n");    // ≤
    printw("Greater/Equal sign          "); addch(ACS_GEQUAL); printw("\n");    // ≥
    printw("Pi                          "); addch(ACS_PI); printw("\n");        // π
    printw("Not equal                   "); addch(ACS_NEQUAL); printw("\n");    // ≠
    printw("UK pound sign               "); addch(ACS_STERLING); printw("\n");  // £

    refresh();
    getch();
    endwin();
    return 0;
}
2025.01.28
スクリーンクリア clear erase
clear()とerase()はどちらもスクリーンを消去する。
int erase(void);
int clear(void);
#include <ncurses.h>

int main()
{
    initscr();
    printw("ABCDEFG");
    getch();
    clear();
    getch();
    printw("0123456");
    getch();
    erase();
    getch();
    endwin();
    return 0;
}
erase()は、画面全体を空白で埋めることで消去し、clear()はターミナルへの初期化を指示して消去する。どちらも消去前の属性は保持される。
2025.01.28
特殊キー入力 keypad
keypad()は、getch()による特殊キーの入力を有効化/無効化する。
int keypad(WINDOW *win, bool bf);
#include <ncurses.h>

int main()
{
    int key = 0;
    initscr();
    noecho();
    keypad(stdscr, TRUE);   //特殊キー(カーソルキーなど)を有効化
    while (key != 'q') {
        key = getch();
        printw("key=%c %04x %04o\n", key, key, key); 
        refresh();
    }
    endwin();
    return 0;
}
2025.01.28
文字列入力 getstr
getstr()は、Enter入力までの文字列の入力を格納する。
int getstr(char *str);
#include <ncurses.h>
#include <locale.h>

int main()
{
    char s[80];
    setlocale(LC_ALL, "");
    initscr();
    echo();
    printw(">>>");
    getstr(s);
    printw("[%s]\n", s);
    getch();
    endwin();
    return 0;
}
getstr()の前に、noecho()ではなく文字列のキー入力を表示するためにecho()を呼び出している。
2025.01.28
RAWモード入力 raw
raw()はキー入力をRAWモードに変更する。
RAWモードは、getch()によりCTRL-Cのような制御コードのキー入力も忠実に取り込むことができる。
int raw(void);
#include <ncurses.h>

int main()
{
    int ch;
    initscr();
    raw();                  // RAWモード
    keypad(stdscr, TRUE);
    noecho();
    while (1) {
        if ((ch = getch()) == KEY_F(1)) {
            break;
        } else {
            printw("key=%c(%02x)\n", ch, ch);
        }
        refresh();
    }
    endwin();
    return 0;
}
key=^A(01)
key=^B(02)
key=^C(03)
key=R(152)
key=S(153)
key=^B(102)
2025.01.28
キー入力タイムアウト halfdelay
halfdelay()は、getch()のキー入力ブロッキングのタイムアウトを設定する。
指定時間を経過してキー入力がない場合、エラー(-1)を返す。引数に指定するタイムアウト時間は0.1秒単位である。
int halfdelay(int tenths);
int cbreak(void);
#include <ncurses.h>

int main()
{
    int ch;
    initscr();
    cbreak();
    keypad(stdscr, TRUE);
    halfdelay(10);
    noecho();
    while (1) {
        if ((ch = getch()) == 'q') {
            break;
        } else {
            printw("key=%c(%d)\n", ch, ch);
        }
        refresh();
    }
    cbreak();
    getch();
    endwin();
    return 0;
}
cbreak()を呼び出すと、halfdelay()が解除される。
cbreak()は、getch()がキー入力をEnterまでバッファリングしない設定を明示的に行うが、halfdelay()の設定を解除して通常のブロッキングに戻すことができる。
2025.01.28
ESCタイムアウト set_escdelay
set_escdelay()は、ESCキーに続く入力待ちのタイムアウトを設定する。引数にはミリ秒単位で指定する。
getch()は、ESCキーの入力があると、続いて入力されるであろうエスケープシーケンスを1秒間待機する。set_escdelay()で短い時間を設定すると、ESCキー押下を即時検出できる。
int set_escdelay(int ms);
#include <ncurses.h>

int main()
{
    int ch;
    initscr();
    cbreak();
    keypad(stdscr, TRUE);
    set_escdelay(100);
    noecho();
    while (1) {
        if ((ch = getch()) == 'q') {
            break;
        } else {
            printw("key=%c(%02x)\n", ch, ch);
        }
        refresh();
    }
    endwin();
    return 0;
}
2025.01.28
キーブロッキング設定 nodelay
nodelay()は、getch()がキー入力があるまでブロックするかどうかを設定する。
bfにTRUEを指定すると、キー入力がなければ即時にERRを返す。
int nodelay(WINDOW *win, bool bf);
#include <ncurses.h>

int main()
{
    int ch;

    initscr();
    raw();
    keypad(stdscr, TRUE);
    cbreak();
    noecho();
    nodelay(stdscr, TRUE);  // キー入力を待たない
    while ((ch = getch()) != 'q') {
        napms(500);
        if (ch == ERR)      // キー入力がない間はERRを返し続ける
            printw("Timeout\n");
        else
            printw("key=%c(%02x) %s\n", ch, ch, keyname(ch));
        refresh();
    }
    mvprintw(0, 0, "EXIT");
    endwin();
    return 0;
}
Timeout
Timeout
Timeout
key=R(152) KEY_NPAGE
Timeout
key=^F(106) KEY_HOME
Timeout
2025.01.28
入力キューに戻す ungetch
ungetch()は、getch()で取得したキー入力の文字をキー入力のキューに戻す。
int ungetch(int ch);
#include <ncurses.h>

int main()
{
    int ch;
    initscr();
    noecho();
    while ((ch = getch()) != 'q') {
        ungetch(ch);        // キー入力をキューに戻す
        ch = getch();       // 戻したキーをキューからすぐに引き出すので、ここで入力待ちにならない
        printw("<%c>", ch);
    }
    refresh();
    endwin();
    return 0;
}
2025.01.28
キー名称取得 keyname
keyname()はgetch()で取得した入力されたキーコードの名前を返す。
char *keyname (int ch);
#include <ncurses.h>

int main()
{
    int ch;
    initscr();
    cbreak();
    keypad(stdscr, TRUE);
    set_escdelay(100);
    noecho();
    while (1) {
        if ((ch = getch()) == 'q') {
            break;
        } else {
            printw("key=%c(%02x) %s\n", ch, ch, keyname(ch));
        }
        refresh();
    }
    endwin();
    return 0;
}
key=R(152) KEY_NPAGE
key=h(168) KEY_END
key=^G(107) KEY_BACKSPACE
key=^[(1b) ^[
key=^D(104) KEY_LEFT
key=    (109) KEY_F(1)
2025.01.28
カラー可否 has_colors
has_colors()とcan_change_color()は、ターミナルのカラー表示可否を返す。
bool has_colors(void);
bool can_change_color(void);
#include <ncurses.h>

int main(int argc,char *argv[])
{
    initscr();
    printw("has colors=%d\n", has_colors());
    printw("can change color=%d", can_change_color());
    getch();
    endwin();
    return (0);
}
has colors=1
can change color=1
2025.01.28
カラー表示 start_color init_pair attrset
init_pair()は、文字色と文字の背景色の組み合わせのカラー番号を定義する。
attrset()は文字修飾の属性を設定する。attrset()で属性を変更した以降に表示する文字に設定した属性が適用される。
カラー番号はCOLOR_PAIR()にカラー番号を指定することで属性値に変換できる。
int init_pair(short pair, short f, short b);
int attrset(int attrs);
COLOR_PAIR(pair)
#include <ncurses.h>

int main(int argc,char *argv[])
{
    initscr();
    start_color();                          // 色の準備
    init_pair(1, COLOR_RED, COLOR_YELLOW);  // 色1 は黄背景に赤文字
    init_pair(2, COLOR_GREEN, COLOR_WHITE);  // 色2 は白背景に緑文字
    init_pair(3, COLOR_YELLOW, COLOR_BLUE); // 色3 は青背景に黄文字

    attrset(COLOR_PAIR(1));         // 色1 を使う 現在の属性を設定。次回まで保持するようだ
    mvaddstr(5,  5, "Hello World");
    attrset(COLOR_PAIR(2));         // 色2 を使う
    mvaddstr(5, 25, "Hello World");
    attrset(COLOR_PAIR(3));         // 色3 を使う
    mvaddstr(5, 45, "Hello World");

    getch();
    endwin();
    return (0);
}
2025.01.28
デフォルトカラー使用 use_default_colors
use_default_colors()を呼び出すことで、ターミナルのデフォルトの文字色を-1として指定できるようになる。
assume_default_colors()は、デフォルト色の文字色と背景色を変更する。
int use_default_colors(void);
int assume_default_colors(int fg, int bg);  
#include <ncurses.h>

int main(int argc,char *argv[])
{
    initscr();
    start_color();
    use_default_colors();
    assume_default_colors(COLOR_RED, COLOR_YELLOW);
    mvprintw(2, 5, "Default Color");
    init_pair(1, COLOR_MAGENTA, -1);    // 背景色にデフォルトを指定(この場合黄色)
    init_pair(2, -1, COLOR_GREEN);      // 文字色にデフォルトを指定(この場合赤)
    attrset(COLOR_PAIR(1));
    mvprintw(3, 5, "Default Color");
    attrset(COLOR_PAIR(2));
    mvprintw(4, 5, "Default Color");
    getch();
    endwin();
    return (0);
}
2025.01.28
RGB再割当 init_color
init_color()は、COLOR_〜のカラーコードの定数のRGB値を再設定する。
int init_color(short color, short r, short g, short b);
#include <ncurses.h>

int main(int argc, char *argv[])
{
    initscr();
    start_color();
    init_color(COLOR_BLUE, 600, 600, 1000); // BLUEの色定義をRGB値で初期化
    init_pair(1, COLOR_BLACK, COLOR_BLUE);
    attrset(COLOR_PAIR(1));     // 背景色が水色に近い青になる
    printw("ABCDEFG");
    getch();
    endwin();
    return 0;
}
2025.01.28
カラーペアの分解 pair_content 
pair_content()は、色のペア番号をフォアグラウンド色と背景色のカラーコードに分解し、引数戻り値に返す。
int pair_content(short pair, short *f, short *b);
#include <ncurses.h>

int main(int argc,char *argv[])
{
    short f, b ;
    initscr();
    start_color();
    use_default_colors();
    init_pair(1, COLOR_YELLOW, COLOR_RED);
    mvprintw(1, 0, "%d %d", COLOR_YELLOW, COLOR_RED);       // 3 1  YELLOWとREDであることがわかる
    pair_content(1, &f, &b);
    mvprintw(2, 0, "colorpair-1 .. Fore=%d Back=%d", f, b); // colorpair-1 .. Fore=3 Back=1
    refresh();
    getch();
    endwin();
    return (0);
}
2025.01.28
背景色 bkgd bkgdset getbkgd
bkgd()は、ターミナル全体すべてのデフォルトの背景色を設定し、呼び出し後直ちに画面全体へ反映する。
bkgdset()は、呼び出した以降から出力した文字に対する背景色を設定する。
何れも、chtypeで指定する引数は背景色だけでなく文字色(フォアグラウンド)も設定できる。
int bkgd(chtype ch);
void bkgdset(WINDOW *win, chtype ch);
#include <ncurses.h>

int main(int argc,char *argv[])
{
    initscr();
    start_color();
    use_default_colors();
    init_pair(1, COLOR_YELLOW, COLOR_BLUE);
    init_pair(2, COLOR_WHITE, COLOR_MAGENTA);
    bkgd(COLOR_PAIR(1));                    // すべての行・カラムに即座に反映
    printw("Background Color\n\n");
    bkgdset(COLOR_PAIR(2));                 // ここからの表示から反映
    mvprintw(4, 0, "Background Color");     // 4と6行目はbkgdset()が適用される
    mvprintw(6, 0, "Background Color");     // 間の5行目はbkgd()の設定が残る
    init_pair(3, COLOR_GREEN, -1);
    attrset(COLOR_PAIR(3));
    mvprintw(7, 0, "Background Color");     // デフォルト背景色の-1はターミナルの設定で適用
    getch();
    endwin();
    return (0);
}

背景色取得

getbkgd()は現在設定されている背景色を取得する。
戻り値のctypes型の文字と属性を合わせた値を返すので実際には属性も含めて取得できる。
chtype getbkgd(WINDOW *win);
ctypesから最後に設定した背景色のペア番号がPAIR_NUMBER()で得られる。
PAIR_NUMBER(attrs);
#include <ncurses.h>

int main(int argc,char *argv[])
{
    chtype c;
    initscr();
    start_color();
    use_default_colors();
    init_pair(1, -1, COLOR_BLUE);       // 背景青
    init_pair(2, -1, COLOR_RED);        // 背景赤
    bkgdset(COLOR_PAIR(1));
    mvprintw(1, 0, "1234567890");       // 青背景で表示
    refresh();
    bkgdset(COLOR_PAIR(2));
    mvprintw(2, 0, "ABCDEFG");          // 赤背景で表示
    c = getbkgd(stdscr);
    refresh();
    mvprintw(3, 0, "color=%d", PAIR_NUMBER(c)); 
    refresh();
    getch();
    endwin();
    return (0);
}
この例の場合は最後に設定した背景色のペア番号の2が得られる。カーソルを1,0に移動してgetbkgd()を行っても、その前の色ペア1になることはない。getbkgd()が返すのは、その座標の文字の背景色ではなく、あくまで最後に設定した背景色である。
1234567890  ⇒ 背景青で表示
ABCDEFG     ⇒ 背景赤で表示
color=2
2025.01.28
属性設定 attrset attr_get
attrset()は、COLOR_PAIR()で変換するカラー属性と、A_BOLDなどの文字修飾属性をフラグとして同時に設定できる。
int attrset(int attrs);
COLOR_PAIR(pair)
#include <ncurses.h>

int main(int argc,char *argv[])
{
    initscr();
    start_color();
    init_pair(1, COLOR_YELLOW, COLOR_BLUE);    // 色1 青地に黄色

    attrset(COLOR_PAIR(1) | A_BOLD);        // 色&強調表示 「|」で属性を複数指定できる
    mvaddstr(0, 0, "Hello World COLOR+BOLD");
    attrset(A_BOLD | A_REVERSE);            // 太字&反転表示
    mvaddstr(2, 0, "Hello World BOLD+REVERSE");
    attrset(COLOR_PAIR(1) | A_REVERSE);     // 色の反転
    mvaddstr(4, 0, "Hello World COLOR+REVERSE");
    attrset(COLOR_PAIR(1) | A_BLINK | A_UNDERLINE);     // 色&点滅&下線
    mvaddstr(6, 0, "Hello World COLOR+BLINK+UNDERLINE");

    getch();
    endwin();
    return (0);
}

属性取得 attr_get

attr_get()は、現在設定されている属性を取得する。
引数戻り値にattr_tの属性値と、pairに色のペア番号が返る。attrsは、A_BOLDなどの属性のビットが設定されて返る。optは現在はほとんど使われていないので通常はNULLでよい。
int attr_get(attr_t *attrs, short *pair, void *opts);
#include <ncurses.h>

int main(int argc, char *argv[])
{
    attr_t attr;        // 32ビット整数
    short cpair;

    initscr();
    start_color();
    init_pair(2, COLOR_RED, COLOR_GREEN);
    attrset(COLOR_PAIR(2) | A_BOLD | A_BLINK);
    printw("ABCDDEF");
    refresh();
    attr_get(&attr, &cpair, NULL);
    mvprintw(1, 0, "colorpair=%d", cpair);
    if (attr & A_BOLD)
        mvprintw(2, 0, "BOLD");
    if (attr & A_BLINK)
        mvprintw(3, 0, "BLINK");
    refresh();
    getch();
    endwin();
    return 0;
}
色の属性がなければpairには0が返る。実際は色のペアも属性なのでattrsの中に含まれている。
ABCDDEF
colorpair=2
BOLD
BLINK
2025.01.28
属性変更 chgat
chgat()は、現在のカーソル位置から指定する文字数の属性を変更する。
attrでA_BOLDなどの文字修飾の属性を与え、pairに色のペア番号を指定する。optsは通常使わないのでNULLでよい。
int chgat(int n, attr_t attr, short pair, const void *opts);
#include <ncurses.h>

int main(int argc, char *argv[])
{
    short cpair;

    initscr();
    start_color();
    init_pair(1, COLOR_BLUE, COLOR_WHITE);    // 色1 は青地に赤文字
    init_pair(2, COLOR_BLACK, COLOR_GREEN);    // 色1 は青地に赤文字
    attrset(COLOR_PAIR(1) | A_BOLD | A_BLINK);
    printw("0123456789");
    move(0, 0);
    chgat(4, A_UNDERLINE, 2, NULL);
    refresh();
    getch();
    endwin();                           /* End curses mode */
    return 0;
}
chgat()で変更した文字数分のカーソルが移動するわけではない。この例では、カーソルはmoveの0,0の位置のままである。
0123456789
    0123    ⇒ 変更した緑バックのアンダーライン
    456789  ⇒ 最初の属性の白背景のBOLD点滅
2025.01.28
属性追加/削除 attron attroff
attron()/attroff()は、現在の属性から指定する属性値を追加/削除する。
int attron(int attrs);
int attroff(int attrs);
#include <ncurses.h>

int main()
{
    initscr();
    curs_set(0);
    attron(A_BOLD | A_UNDERLINE);
    mvprintw(0, 0, "Hello World  BOLD+UNDERLINE ON");
    attroff(A_BOLD | A_UNDERLINE);
    mvprintw(2, 0, "Hello World  BOLD+UNDERLINE OFF");
    getch();
    endwin();
    return 0;
}
2025.01.28
属性を設定して文字出力 addch
addch()は、文字と属性をフラグとして設定して表示する。
int addch(chtype ch)
#include <ncurses.h>

int main()
{
    initscr();
    curs_set(0);
    addch('A' | A_BOLD | A_UNDERLINE);
    addch('B' | A_BLINK);
    addch('C');
    getch();
    endwin();
    return 0;
}
2025.01.28
属性のリセット
A_NORMALは、属性のリセットを意味する。
attrset()により設定することで、全て通常(デフォルト)の属性に戻すことができる。
#include <ncurses.h>

int main(int argc, char *argv[])
{
    initscr();
    curs_set(0);
    attrset(A_BOLD | A_UNDERLINE);
    mvprintw(1, 0, "0123456789");
    attrset(A_NORMAL);              // 属性をリセットする
    mvprintw(3, 0, "0123456789");
    refresh();
    getch();
    endwin();
    return 0;
}
2025.01.28
スクロール scrollok scroll scrl

スクロール許可

scrollok()は、スクロールを許可する。
int scrollok(WINDOW *win, bool bf);
#include <ncurses.h>

int main()
{
    initscr();
    scrollok(stdscr, TRUE);     //// スクロール可
    for (int i = 0; getch() != 'q'; i++) {
        printw("%03d ABCDEFG\n", i);
        refresh();
    }
    endwin();
    return 0;
}
例の場合、scrollok()を呼び出さなければ、表示が最下段に到達してもスクロースせずに最下段に表示し続ける結果になる。

行スクロール

scroll()は、スクリーン全体を1行スクロールダウンさせる。
scrl()は、引数に指定する行数をスクロールする。行数の値が正数ならスクロールダウン、負数ならスクロールアップ。
int scroll(WINDOW *win);
int scrl(int n);
#include <ncurses.h>

int main()
{
    initscr();
    scrollok(stdscr, TRUE);     //// スクロール可
    mvprintw(0, 0, "001 ABCDEFG\n");
    mvprintw(1, 0, "002 ABCDEFG\n");
    mvprintw(2, 0, "003 ABCDEFG\n");
    mvprintw(3, 0, "004 ABCDEFG\n");
    refresh();
    getch();
    scroll(stdscr);     // キーを押すと1行スクロールダウン
    getch();
    scrl(-2);           // もう一度キーを押すと2行スクロールアップ
    refresh();
    getch();
    scrl(4);            // もう一度キーを押すと4行スクロールダウン
    refresh();
    getch();
    endwin();
    return 0;
}
(0)             (1)             (2)             (3)
001 ABCDEFG     002 ABCDEFG                     004 ABCDEFG
002 ABCDEFG     003 ABCDEFG
003 ABCDEFG     004 ABCDEFG     002 ABCDEFG
004 ABCDEFG                     003 ABCDEFG
                                004 ABCDEFG
2025.01.28
文字削除 delch
delch()は、現在カーソル位置の文字を削除する。
deleteln()は、現在カーソル行を削除する。
int delch(void);
int deleteln(void);
#include <ncurses.h>

int main()
{
    initscr();
    mvprintw(0, 0, "ABCDEFG");
    mvprintw(1, 0, "1234567");
    mvprintw(2, 0, "HIJKLMN");
    move(0, 3);
    getch();
    delch();    // (0, 3)の「D」を削除
    refresh();
    getch();
    deleteln(); // 行を削除
    refresh();
    getch();
    endwin();
    return 0;
}
(1)         (2)
ABCEFG      1234567
1234567     HIJKLMN
HIJKLMN
2025.01.28
行末・最下段まで削除 clrtoeol clrtobot
clrtoeol()は、現在のカーソル位置から行末を削除する。
clrtobot()は現在のカーソル位置から最下行までを削除する。
int clrtoeol(void);
int clrtobot(void);
#include <ncurses.h>

int main()
{
    int i;
    initscr();
    noecho();
    for (i = 0; i < 10; i++)
        mvprintw(i, 0, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
    refresh();
    move(3, 4);
    clrtoeol();
    move(6, 10);
    clrtobot();
    getch();
    endwin();
    return 0;
}
この結果は、4行目の5文字目から行末まで削除、6行目の11文字目から右と下が削除になる。
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAA
2025.01.28
カーソル座標取得 getyx
getyx()は現在のカーソル位置の行・桁(y, x)を取得する。
getyz()はマクロ関数であり、yとxは引数戻り値である。
void getyx(WINDOW *win, int y, int x);
#include <ncurses.h>

int main(int argc, char *argv[])
{
    int c;
    int y, x;

    initscr();
    noecho();
    while (1) {
        if ((c = getch()) == 'q')
            break;
        addch(c);
        getyx(stdscr, y, x);    // 現在のカーソル座標取得
        mvprintw(5, 0, "(%d %d)", y, x);
        move(y, x);
        refresh();
    }
    endwin();                           /* End curses mode */
    return 0;
}
2025.01.28
カーソル位置の文字取得 inch 
inch()は現在カーソル位置の属性を含む文字を返す。
chtypeはattr_tと同じであり、文字と属性が設定されている。文字はA_CHARTEXTのビットで取得できる。カラー番号はPAIR_NUMBER()で取得できる。
chtype inch(void);
#include <ncurses.h>

int main()
{
    chtype c;
    initscr();
    start_color();
    use_default_colors();
    noecho();
    init_pair(1, COLOR_YELLOW, -1);
    attrset(COLOR_PAIR(1) | A_BLINK | A_UNDERLINE);
    mvprintw(0, 0, "ABCDEFGHIJKLMN");
    refresh();
    move(0, 5);
    c = inch();
    attrset(A_NORMAL);
    mvprintw(2, 0, "(%c) COL=%d", c & A_CHARTEXT, PAIR_NUMBER(c));
    if (c & A_BOLD)
        printw(" BOLD");
    if (c & A_BLINK)
        printw(" BLINK");
    if (c & A_UNDERLINE)
        printw(" UNDERLINE");

    //// y=2から属性を変えた後で、その前後の行の座標の文字をinch()で取得すると、
    //// それぞれの表示している属性が返るので、
    //// 端末に表示している文字は個別に保持されていることがわかる。

    refresh();
    getch();
    endwin();
    return 0;
}
ABCDEFGHIJKLMN      ⇒アンダーラインで点滅

(F) COL=1 BLINK UNDERLINE
マルチバイト文字はinch()では正しく取得できない。マルチバイト文字の取得はinnwstr()を使う。
2025.01.28
カーソルから文字列取得 instr innstr innwstr
instr()、innstr()は現在のカーソル位置から表示されている文字列を取得する。
instr()はカーソル位置からその行全体を取得する。innstr()はカーソル位置からの取得するサイズを指定する。
int instr(char *str);
int innstr(char *str, int n);
#include <ncurses.h>
#include <locale.h>

int main()
{
    char s[80];
    int len;
    setlocale(LC_ALL, "");      //// ""の場合は環境変数LANGが適用される
    initscr();
    mvprintw(0, 0, "ABCDEFGHIJKLMN");
    mvprintw(1, 0, "01234あいうえお");
    move(0, 2);
    len = instr(s);
    mvprintw(2, 0, "[%s] len=%d", s, len); 
    move(1, 4);
    len = innstr(s, 4);
    mvprintw(4, 0, "[%s] len=%d", s, len); 
    refresh();
    getch();
    endwin();
    return 0;
}

マルチバイト文字の場合

innwstr()は、現在カーソル位置から指定する文字数の表示文字を取得する。
ワイド文字も半角文字も1文字として数える。
int innwstr(wchar_t *wstr, int n);
#include <ncurses.h>
#include <locale.h>
#include <wchar.h>

int main()
{
    wchar_t wc[10];
    attr_t attr;
    setlocale(LC_ALL, "");
    initscr();
    noecho();
    attrset(A_BOLD);
    mvprintw(0, 0, "あいうABCD"); 
    refresh();
    move(0, 4);
    attr_get(&attr, NULL, NULL);
    innwstr(wc, 3);
    move(2, 0);
    addwstr(wc);
    if (attr & A_BOLD)
        mvprintw(3, 0, "BOLD");
    refresh();
    getch();
    endwin();
    return 0;
}
あいうABCD

うAB
BOLD
2025.01.28
ウィンドウ newwin box
newwin()によりウィンドウを作成し、WINDOW構造体のポインタを返す。
取得したWINDOW構造体は、第一引数がWINDOW *winとされている関数に与えることで、操作対象のウィンドウを指定できる。
newwin()が返すWINDOW構造体のデータは、ウィンドウを終了するときにdelwin()で開放しなければならない。
box()は、指定するウィンドウに罫線文字により外枠を表示する。
引数verch/horchに縦線/横線に使用する文字を指定できる(角を指定できない)。verch/horchに0を指定すると、デフォルトの罫線が使用される。
WINDOW *newwin(int nlines, int ncols, int begin_y, int begin_x);
int delwin(WINDOW *win);
int box(WINDOW *win, chtype verch, chtype horch);
#include <ncurses.h>

int main(int argc, char *argv[])
{
    WINDOW *local_win;
    initscr();
    noecho();
    cbreak();
    local_win = newwin(5, 10, 2, 3);
    box(local_win, 0 , '-');
    mvwprintw(local_win, 1, 1, "01234567890");
    refresh();              // 何も書いてないが元スクリーンもrefreshする必要がある
    wrefresh(local_win);    // ウィンドウを更新
    getch();
    delwin(local_win);
    endwin();
    return 0;
}
2025.01.28
ウィンドウの重なり overlay overwrite

透明なウィンドウとしての重なり

overlay(win1, win2)は、win1のウィンドウはwin2に上書きされないように設定する。
int overlay(const WINDOW *srcwin, WINDOW *dstwin);
#include <ncurses.h>

int main(int argc, char *argv[])
{
    WINDOW *win1, *win2;

    initscr();
    noecho();
    start_color();
    init_pair(1, COLOR_WHITE, COLOR_BLUE);
    refresh();
    win1 = newwin(7, 7, 5, 5);
    win2 = newwin(7, 7, 7, 8);
    wbkgd(win1, COLOR_PAIR(1));
    mvwprintw(win1, 0, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRST");
    mvwprintw(win2, 0, 0, "0123456789001234567890012345678900123456789012");
    overlay(win1, win2);
    //// overlayによりwin1が上になる
    wrefresh(win1);
    wrefresh(win2);
    getch();
    delwin(win1);
    delwin(win2);
    endwin();
    return 0;
}
上の場合、overlay()を使わない場合は、win1の一部の座標に重ねてwin2が上書きするように表示される。overley()によりwin1が上に見えるようになる。
ABCD..のウィンドウは背景色が青である。

     ABCDEFG
     HIJKLMN
     OPQRSTU456
     VWXYZAB012
     CDEFGHI789
     JKLMNOP345
     QRST789001
        2345678
        9012
overwrite()と違うのは、overlay()は上になる方の文字がない部分は「透明」という扱いである。ただし、win1の文字がある部分は上になるが、最後の方の文字がない空白部分(RQSTの次の3文字分)は、下のwin2の文字が現れる。

上のウィンドウの上書き

overwrite(win1, win2)は、win1のウィンドウはwin2に上書きされないように設定する。
int overwrite(const WINDOW *srcwin, WINDOW *dstwin);
#include <ncurses.h>

int main(int argc, char *argv[])
{
    WINDOW *win1, *win2;

    initscr();
    noecho();
    start_color();
    init_pair(1, COLOR_WHITE, COLOR_BLUE);
    refresh();
    win1 = newwin(7, 7, 5, 5);
    win2 = newwin(7, 7, 7, 8);
    wbkgd(win1, COLOR_PAIR(1));
    mvwprintw(win1, 0, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRST");
    mvwprintw(win2, 0, 0, "0123456789001234567890012345678900123456789012");
    overwrite(win1, win2);
    wrefresh(win1);
    wrefresh(win2);
    getch();
    delwin(win1);
    delwin(win2);
    endwin();
    return 0;
}
上の場合、overwrite()を使わない場合は、win1の一部の座標に重ねてwin2が上書きするように表示される。overwrite()によりwin1が上に見えるようになる。
ABCD..のウィンドウは背景色が青である。

     ABCDEFG
     HIJKLMN
     OPQRSTU456
     VWXYZAB012
     CDEFGHI789
     JKLMNOP345
     QRST   001
        2345678
        9012
overlay()と違うのは、overwrite()は上になる方の文字がない部分も空白として上書きされることである。win1の文字がある部分は上になるが、最後の方の文字がない空白部分(RQSTの次の3文字分)は、スペースという扱いであり、この部分も下のウィンドウの文字は表示されない。
2025.01.28
ウィンドウの内容コピー copywin
copywin()はウィンドウの一部の矩形範囲を、他のウィンドウへコピーする。
int copywin(const WINDOW *srcwin, WINDOW *dstwin,
    int sminrow, int smincol, int dminrow, int dmincol, int dmaxrow, int dmaxcol,
    int overlay);
sminrow smincol     コピー元srcwinの座標
dminrow dmincol     コピー先dstwinの貼り付け座標(左上)
dmaxrow dmaxcol     コピー先dstwinの貼り付け座標(右下)
overlay     trueはsrcwinとdstwinがoverlay()と同様な関係
#include <ncurses.h>

int main(int argc, char *argv[])
{
    WINDOW *win1, *win2;

    initscr();
    noecho();
    start_color();
    init_pair(1, COLOR_WHITE, COLOR_BLUE);
    win1 = newwin(7, 7, 5, 5);
    win2 = newwin(7, 7, 5, 15);
    wbkgd(win1, COLOR_PAIR(1));
    mvwprintw(win1, 0, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRST");
    copywin(win1, win2, 2, 2, 2, 2, 4, 4, true);
    //copywin(win1, win2, 0, 0, 0, 0, 6, 6, true);      //// これは全コピーになる
    refresh();
    wrefresh(win1);
    wrefresh(win2);
    getch();
    delwin(win1);
    delwin(win2);
    endwin();
    return 0;
}
コピー元の左上座標だけ指定し、どの矩形範囲かはコピー先の範囲で決定される。上の場合、win1の(2,2)を左上としてwin2の(2,2)-(4,4)にコピーするので、win1の(2,2)から3x3の矩形がコピーされる。


     ABCDEFG
     HIJKLMN
     OPQRSTU     QRS
     VWXYZAB     XYZ
     CDEFGHI     EFG
     JKLMNOP
     QRST
2025.01.28
ウィンドウ座標・サイズ取得 getbegyx getmaxyx
getbegyx()は、ウィンドウ現在の座標をy, xに返す。
getmaxyx()は、ウィンドウの現在の行数と桁数をy, yに返す。
void getbegyx(WINDOW *win, int y, int x);
void getmaxyx(WINDOW *win, int y, int x);
#include <ncurses.h>

int main(int argc, char *argv[])
{
    WINDOW *win;
    int x, y; 

    initscr();
    noecho();
    win = newwin(5, 10, 5, 8);
    box(win, 0, 0);
    refresh();
    wrefresh(win);
    getbegyx(win, y, x);
    mvprintw(1, 0, "beg x=%d y=%d", x, y);  //// beg x=8 y=5
    getmaxyx(win, y, x);
    mvprintw(2, 0, "max x=%d y=%d", x, y);  //// max x=10 y=5
    wrefresh(win);
    getch();
    delwin(win);
    endwin();
    return 0;
}
beg x=8 y=5
max x=10 y=5


        ┌────────┐
        │        │
        │        │
        │        │
        └────────┘
2025.01.28
ウィンドウ座標判定 wenclose
wenclose()は、座標がウィンドウの範囲に入っているかどうかを判定する。
指定するウィンドウの範囲であればTRUEを返す。
bool wenclose(const WINDOW *win, int y, int x);
#include <ncurses.h>

int main(int argc, char *argv[])
{
    int c;
    WINDOW *win1, *win2;
    MEVENT me;
    mmask_t old;

    initscr();
    noecho();
    keypad(stdscr, TRUE);
    mousemask(ALL_MOUSE_EVENTS, &old);
    refresh();
    win1 = newwin(5, 10, 2, 3);
    win2 = newwin(5, 10, 8, 3);
    box(win1, 0 , 0);
    box(win2, 0 , 0);
    wrefresh(win1);
    wrefresh(win2);
    c = getch(); 
    while(1) { 
        if (c == 'q')
            break;
        if (c == KEY_MOUSE) {
            if (getmouse(&me) == OK) {
                if (wenclose(win1, me.y, me.x))
                    mvprintw(0, 0, "Win1 clicked");
                if (wenclose(win2, me.y, me.x))
                    mvprintw(0, 0, "Win2 clicked");
                refresh();
            }
        }
        c = getch(); 
    }
    delwin(win1);
    delwin(win2);
    mousemask(old, NULL);
    endwin();
    return 0;
}
例は、2つのウィンドウが表示され、どちらのウィンドウでクリックが発生したかを表示する。
Win2 clicked

   ┌────────┐
   │        │
   │        │
   │        │
   └────────┘

   ┌────────┐
   │        │
   │        │
   │        │
   └────────┘

2025.01.28
ウィンドウ表示更新 wnoutrefresh doupdate
wnoutrefresh()とdoupdate()は、ウィンドウを指定してスクリーンへ反映するwrefresh()の内部処理である。
wrefresh()は、wnoutrefresh()でウィンドウの仮想スクリーンを更新し、doupdate()でスクリーン反映を行う。
複数のウィンドウを表示する場合に、個別のウィンドウの更新時にこれらの関数を各々呼び出すのではなく、全てのウィンドウについてwnoutrefresh()で仮想スクリーンの更新を済ませてから、doupdate()の一回でスクリーン反映すると効率がよい。
int wnoutrefresh(WINDOW *win);
int doupdate(void);
#include <ncurses.h>

int main(int argc, char *argv[])
{
    WINDOW *win1, *win2;

    initscr();
    noecho();
    win1 = newwin(5, 10, 3, 3);
    win2 = newwin(5, 10, 8, 3);
    box(win1, 0 , 0);
    box(win2, 0 , 0);
    mvwprintw(win1, 1, 1, "0123456789");
    mvwprintw(win2, 1, 1, "ABCDEFGHIJ");
    refresh();
    wnoutrefresh(win1);
    wnoutrefresh(win2);
    doupdate();
    getch();
    delwin(win1);
    delwin(win2);
    endwin();
    return 0;
}
2025.01.28
縦横罫線 vline hline
hline()・vline()はそれぞれ水平線・垂直線の罫線文字を表示する。
int hline(chtype ch, int n);
int vline(chtype ch, int n);
#include <ncurses.h>

int main(int argc, char *argv[])
{
    initscr();
    noecho();
    move(2, 5);
    hline(A_NORMAL , 20);   // 20文字の水平ライン状の文字
    vline(A_NORMAL, 5);     // 5文字の垂直ライン状の文字
    refresh();
    getch();
    endwin();
    return 0;
}
     │───────────────────
     │
     │
     │
     │
引数に属性を指定できるが、文字色やA_BOLDなどの属性を指定してもうまく表示できないことがある。
2025.01.28
マウス入力 mousemask getmouse
mousemask()は、指定するマウスイベントをgetch()のキー入力でKEY_MOUSEというキーコードとして取得できるように設定する。
通常は全てのマウスイベントを示すALL_MOUSE_EVENTSを指定する。oldmaskには設定前のマウスイベントの状態を保存する。保存が不要な場合はNULLを指定する。マウスイベントの取得を終了するときに保存したoldmaskをmousemask()で設定することでマウスイベントの設定を戻すことができる。
getmouse()は、KEY_MOUSE入力時のマウスイベントの情報を取得する。
NCURSES_MOUSE_MASK()マクロは、MEVENTのbstateで得られるイベント状態をイベントの定義でチェックする。
mmask_t mousemask(mmask_t newmask, mmask_t *oldmask);
int getmouse(MEVENT *event);
NCURSES_MOUSE_MASK(ボタン番号, イベントの種類)

typedef struct {
   short id;         // ID to distinguish multiple devices
   int x, y, z;      // event coordinates
   mmask_t bstate;   // button state bits
} MEVENT;
#include <ncurses.h>

int main(int argc, char *argv[])
{
    MEVENT me;
    int c = 0;
    mmask_t old;

    initscr();
    noecho();
    keypad(stdscr, TRUE);
    mousemask(ALL_MOUSE_EVENTS, &old);
    c = getch(); 
    while(1) { 
        if (c == 'q')
            break;
        if (c == KEY_MOUSE) {
            if (getmouse(&me) == OK) {
                printw("ID=%d (%3d %3d) ", me.id, me.x, me.y); 
                for (int i = 1; i <= 5; i++) {
                    if (me.bstate == NCURSES_MOUSE_MASK(i, NCURSES_BUTTON_RELEASED))
                        printw("BUTTON %d RELEASED\n", i); 
                    if (me.bstate == NCURSES_MOUSE_MASK(i, NCURSES_BUTTON_PRESSED))
                        printw("BUTTON %d PRESSED\n", i); 
                    if (me.bstate == NCURSES_MOUSE_MASK(i, NCURSES_BUTTON_CLICKED))
                        printw("BUTTON %d CLICKED\n", i); 
                    if (me.bstate == NCURSES_MOUSE_MASK(i, NCURSES_DOUBLE_CLICKED))
                        printw("BUTTON %d DOUBLECLICKED\n", i); 
                }
                refresh();
            }
        }
        c = getch(); 
    }
    mousemask(old, NULL);
    getch();
    endwin();
    return 0;
2025.01.28
マウスクリック判定時間 mouseinterval
mouseinterval()は、マウスボタンイベントがクリックとして判定する「ボタン押す-離す」間の最大時間をミリ秒で指定する。
int mouseinterval(int erval);
#include <ncurses.h>

int main(int argc, char *argv[])
{
    MEVENT me;
    int c = 0;
    mmask_t old;

    initscr();
    noecho();
    keypad(stdscr, TRUE);
    mousemask(ALL_MOUSE_EVENTS, &old);
    mouseinterval(100);         //// クリックの押して離す許容時間msec

    c = getch(); 
    while(1) { 
        if (c == 'q')
            break;
        if (c == KEY_MOUSE) {
            if (getmouse(&me) == OK) {
                if (me.bstate & BUTTON1_CLICKED)
                    mvprintw(0, 0, "Clicked"); 
                else
                    mvprintw(0, 0, "ON/OFF "); 
                refresh();
            }
        }
        c = getch(); 
    }
    mousemask(old, NULL);
    endwin();
    return 0;
}
10(ms)を指定すると、ほとんどマウスクリックが検出されなくなる。
2025.01.28
スクリーン保存・復元 def_prog_mode reset_prog_mode
def_prog_mode()は現在のターミナルの状態を保存する。
reset_prog_mode()で保存した状態を復元して続きから端末制御を継続することができる。
int def_prog_mode(void);
int reset_prog_mode(void);
#include <ncurses.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    initscr();
    printw("Hello World\n");
    refresh();
    getch();
    def_prog_mode();                // ttyモードを保存
    endwin();                       // 一旦終了
    system("/bin/sh");              // shを起動。exitで終了
    reset_prog_mode();              // 保存したttyモードに復帰
    refresh();
    getch();
    endwin();
    return 0;
}
2025.01.28
スクリーンファイル保存・復元 scr_dump scr_restore
scr_dump()は、現在のスクリーンの表示とその属性、カーソルの位置をファイルに保存する。
scr_restore()は、保存したファイルからスクリーンを復元する。
int scr_dump(const char *filename);
int scr_restore(const char *filename);
#include <ncurses.h>

int main(int argc, char *argv[])
{
    int i; 

    initscr();
    noecho();
    cbreak();
    for (i = 0; i < 5; i++) 
        mvprintw(i, 0, "%02d ABCDEFGHIJKLMN", i);
    refresh();
    scr_dump("./scdump.dat");       // 画面状態をファイルへ保存
    getch();
    clear();                        // 画面クリア
    getch();
    scr_restore("./scdump.dat");    // 保存したファイルで画面復元
    refresh();
    getch();
    endwin();
    return 0;
}
2025.01.28
ウィンドウファイル保存・復元 putwin getwin
putwin()は、指定するウィンドウの状態を属性も含めてファイルに保存する。
getwin()は、その保存したファイルをスクリーンに復元させる。
int putwin(WINDOW *win, FILE *filep);
WINDOW *getwin(FILE *filep);
#include <ncurses.h>

int main(int argc, char *argv[])
{
    WINDOW *win;
    int x, y; 
    FILE *fp;

    initscr();
    noecho();
    start_color();
    init_pair(1, COLOR_WHITE, COLOR_BLUE);
    win = newwin(5, 10, 5, 8);
    box(win, 0, 0);
    wbkgd(win, COLOR_PAIR(1));
    mvwprintw(win, 1, 1, "ABCDEFG");
    refresh();
    wrefresh(win);
    fp = fopen("./win.dat", "w");   // テキストファイルで開く
    putwin(win, fp);                // win.datにウィンドウを保存
    fclose(fp);

    getch();
    delwin(win);
    endwin();
    getch();        // 画面が消えてキーを押すともう一度開く

    initscr();
    noecho();
    refresh();
    fp = fopen("./win.dat", "r");
    win = getwin(fp);               //// win.datに保存したウィンドウを復元
    fclose(fp);
    wrefresh(win);
    getch();
    delwin(win);
    endwin();
    return 0;
}

        ┌────────┐
        │ABCDEFG │
        │        │
        │        │
        └────────┘
2025.01.28
スリープ napms
napms()は、指定時間の実行を待機する。sleep()と同じである。
時間はミリ秒単位で指定する。
int napms (int ms);
#include <ncurses.h>

int main(int argc, char *argv[])
{
    int i;
    initscr();
    noecho();
    for (i = 0; i < 5; i++) {
        mvprintw(i, 0, "wait"); 
        refresh();
        napms(1000);        //// sleep msec
    }
    endwin();
    return 0;
}