GNU readline
GNU readline は文字列入力用ライブラリです。
このライブラリを使って入力を行うと、bash のように、↑キーを押すと履歴の参照が可能だったり、タブキーで入力文字列の補完が可能だったりします。
使うこと自体は初めてではありませんが、今回まじめに使ってみたので(readline/history.h の構造体や関数を確認し、履歴を利用するアプリケーションを作っていた)、そのまとめです。
GNU readline を使うには
/usr/include/readline/readline.h
/usr/include/readline/history.h
BSD や Linux ディストリビューションで提供されているパッケージなどからインストールが可能です。
上記ヘッダーファイルを使います。
文字列入力
char *readline(const char *prompt);
引数に入れた文字列を入力時のプロンプト文字列として、文字列入力を行います。
readline が入力された文字列分のメモリ領域を確保し、先頭ポインタを返してくれます。
メモリ領域の開放は自分で行う必要があります。
履歴への登録
void add_history(const char *line);
指定した文字列を履歴へ登録します。
readline から入力した文字列しか登録できないというわけではなく、好きな文字列を登録することが可能です。
履歴の読み出し、書き出し
int read_history(const char *filename)
指定した履歴ファイルを読み出します。
成功すると 0 を返します。
int write_history(const char *filename)
指定したファイルに履歴を書き出します。
成功すると 0 を返します。
履歴の参照
typedef struct _hist_entry {
char *line;
char *timestamp;
histdata_t data;
} HIST_ENTRY;
履歴はこのような構造体に保存されています。
HIST_ENTRY *current_history(void)
現在の行を返します。
HIST_ENTRY *previous_history(void)
1つ前の行を返します。
HIST_ENTRY **history_list(void)
HIST_ENTRY の配列を返します。
他に使える関数
/usr/include/readline/history.h を参照することで使い方を知ることができます。
サンプルコード
HelloReadline.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <readline/readline.h>
#include <readline/history.h>
int main(int argc, char *argv[]) {
/* ループに使うインデックスです。 */
int i = 0;
/* 入力された文字列の参照に使います。 */
char *str = NULL;
/* 履歴リストの参照に使います。 */
HIST_ENTRY **historyList = NULL;
/* 文字列入力プロンプトを表示します。 */
while(NULL != (str = readline("input "))) {
/* 何も入力されなかった場合は無視します。メモリの解放を忘れないでください。 */
if(*str == '\0') {
free(str);
continue;
}
/* quit が入力されたらループを抜けます。文字列比較には strcmp を使用します。 */
if(strcmp(str, "quit") == 0) {
free(str);
break;
}
/* 入力された文字列を履歴へ登録します。 */
add_history(str);
/* 入力された文字列をそのまま出力します。 */
printf("output: %s\n", str);
free(str);
}
printf('-- History List --\n');
/* 履歴リストを取得します。 */
historyList = history_list();
/* 履歴を1行ずつ参照します。 */
while(historyList[i] != NULL) {
/* 履歴を1行取得します。 */
HIST_ENTRY *history = historyList[i];
/* 履歴に含まれる文字列を出力します。 */
printf("%s\n", history->line);
/* インデックスを次に進めます。 */
i++;
}
/* 履歴リストをファイルに書き出します。 */
write_history("history.txt");
/* プログラムを終了します。 */
return EXIT_SUCCESS;
}
1. quit が入力されるまで、入力された文字列をそのまま出力する。
2. quit が入力されたら、それまでに入力された履歴リストを出力する。
3. 履歴リストをファイルに出力する。
コンパイル
gcc -o HelloReadline -Wall -lreadline -lcurses HelloReadline.c
リンカオプションが必要です。


