GNU readline

前回 jxa で readline を使ったけどさ。
やっぱり C でも使いたいヤン。

GNU readline | Apribase

タブキー保管ができたり上矢印キーで履歴が辿れたり、まさに端末って感じ。
gets や scanf は非推奨なんだし、端末入力はコレに統一でいいじゃん。

Fedora では libreadline.so は最初から入っている。
でも C のヘッダは無いので以下のコマンドでヘッダを追加する必要がある。

# ncurses ヘッダも依存関係で入るけど気にしない。
sudo dnf install readline-devel

macOS では Command Line Tools の導入で readline.h も入ってくる。
GNU のものではなく互換品だったりするけど。
なので検索すると editline/readline.h と指定、なんて出てくると思う。
現在は以下にシンボリックリンクがあるので readline/readline.h のままでいい。

/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/readline/readline.h

ビルドするにはどちらも -l リンカオプションは必要。

#include <stdio.h>
#include <stdlib.h> /* free() */
#include <string.h> /* strcmp() */
#include <readline/readline.h>
#include <readline/history.h>

/*
    Fedora: gcc -lreadline src.c
    macOS:  clang -lreadline src.c
*/

int main(void) {
    char *s;
    printf("usage: exit 又は Ctrl+D で終了\n");
    while (1) {
        s = readline(">> ");
        if (s == NULL) { /* Ctrl+D */
            printf("\n");
            break;
        } else if (strcmp(s, "exit") == 0) {
            free(s);
            break;
        } else if (*s == '\0')
            printf("なんか打ち込めよ!\n");
        else
            printf("%s はカッコイイ!!!\n", s);
        add_history(s);
        free(s);
    }
    return 0;
}

で。

clang_readline

Fedora, macOS 共に上矢印キーで履歴が辿れるし control+D も使える。
macOS の history.h って実は readline.h へのリンクなので不要だけど互換のために。
string.h 等の指定も省略可能だけど警告がウザいので入れたほうがいい。