コマンドライン引数の取得 その2
関数getopt_longは長い形式のオプションの取得に便利な関数である.これはGNU拡張らしい.長いオプションは大抵--で始まる.
getopt_longはgetoptを拡張して--で始まる長い形式のオプションを解釈できるようにした関数である.POSIX準拠ではなく,GNU独自のものらしい.長い形式のオプションは一意に決まる限り短く省略できる.例えば,
--foo --foovarの二つのみをオプションに持つコマンドがあった場合,--foovarは一意に決まる省略形--foovでも解釈される.
int getopt_long(int argc, char * const argv[],
const char *optstring,
const struct option *longopts, int *longindex);
各引数について以下に示す.
- argc,*argv[]
- main関数の引数をそのまま渡す.
- *optstring
- getoptと同様,短い形式のオプションを示す.
- *longopts
- 長い形式のオプションを示す構造体optionの配列.
- *longindex
- マッチした長い形式のオプションに対する*longoptsのインデクス.
struct option {
const char *name;
int has_arg;
int *flag;
int val;
};
各フィールドの説明を以下に示す.
- *name
- オプション名.
- has_arg
- このオプションが値を持つかどうかを示す.
- no_argument
- 値を持たない
- required_argument
- 値を必ず持つ
- optional_argument
- 値を持っても持たなくてもよい
- *flag
- 次のフィールドvalを設定する変数へのポインタ.これがNULLの場合はgetopt_longはvalを返す.NULL以外ならvalを*flagに設定して0を返す.もちろんオプションが見付からない場合,*flagは設定されない.
- val
- *flagに設定する値.
前項のgetopでは外部変数の説明がやっつけだったので,ここで改めて記述する.
- char *optarg
- 次に検査するargv要素.これはgetoptを呼んだあとでは,次のオプション,またはオプションに続くテキストを指す.
- int optind
- オプションを順に読み込むためにgetoptが使用する.オプションの処理が終ったとき,optind < argcなら,不正なオプションがあることになる.
- int opterr
- 0にするとgetoptが表示するエラーメッセージを抑制する.
- optopt
- 引数でない文字を検出したときに,その文字を格納する.
getoptの引数optstringで,処理するオプションをgetoptに伝える.これも前項でやっつけたので,ここで改めてやっつける.
- 例1:"abc"
- a,b,cがオプション
- 例2:"ab:c"
- a,b,cがオプション.bは値を取る.
- 例3:"ab::c"
- a,b,cがオプション.bは値を取ってもとらなくてもよい.
- 例4:"+abc"
- a,b,cがオプションで,非オプション文字列を検出するとただちにプログラムを終了する.環境変数POSIXLY_CORRECTが設定されている場合も同様の動作をする.
- 例5:"-abc"
- a,b,cがオプションで.非オプション文字は文字コード1の文字として扱われる.オプションの順番は任意だが,その順番は意味を持つようにする必要がある(よくわからない).
以上を踏まえてgetopt_longを使用したサンプルを以下にしめす.
以下に実行結果を示す.
./a.out --first_long_option --sec 5 --t 6 --four
=====================================
opt = 1
options[0] : first_long_option
=====================================
opt = 1
options[1] : second_long_option
optarg = 5
=====================================
opt = 0
options[2] : third_long_option
optarg = 6
flag = 2
=====================================
opt = 0
options[3] : fourth_long_option
flag = 3
=====================================
opt = -1
./a.out --first_long_option --sec 5 --t 6 --f
=====================================
opt = 1
options[0] : first_long_option
=====================================
opt = 1
options[1] : second_long_option
optarg = 5
=====================================
opt = 0
options[2] : third_long_option
optarg = 6
flag = 2
=====================================
./a.out: option `--f' is ambiguous
opt = 63
unknown argment
=====================================
opt = -1
二番目実行では--fとしたが,--first_long_optionと--fourth_long_optionの判別できないので怒られた.他にもいろんなオプションの渡し方が可能だが省略.
getopt_long_onlyは,-で始まるオプションも長い形式のオプションとして扱われる.そして-で始まって長い形式のオプションとカブらないときに,短いオプションとして扱われる.

