これまで関数の引数については学んだが、main()
関数については
常に引数はなかった。しかし、通常 Unix などで用いるコマンドの多くは
C言語で書かれており、それらにはオプションと呼ばれるものを指定する
事が可能である。例えば、ファイルをコピーするのに用いられる cp コマンド
は通常二つのコマンドライン引数を与え、
> cp test1 test2 |
のように使う。これによって、test1 のファイルの中身が test2 に コピーされる。つまり、C言語ではこうしたコマンドラインオプション を扱う事が出来る訳である。
コマンドラインに与えられた文字列は、空白を区切りとして複数の
文字列に分けられ、それぞれの文字列へのポインタが main()
関数
に与えられるようになっている。当然、それらの文字列がいくつあるか
が分からないと困るので、main()
関数に与えられる引数は2つの
要素からなる。一つは、コマンドラインオプションの数と、それぞれの
コマンドラインオプションの文字列へのポインタである。
上の例の場合、コマンドラインオプションの数は 3 個である。それぞれの
コマンドラインオプションは、"cp"
, "test1"
, "test2"
という文字列になる。(実際、コマンド自体がオプションに入っているのは、
それなりに便利な事があり、自分自身の名前を知る簡単な方法にもなって
いる。(但し、Java などでは取り扱いが異なるように、一般にコマンド
ラインに与えられたオプションをどう扱うかはそれぞれの言語システム
によって異なるので注意しよう。)
これらを扱うには、以下のように行う。
main( int argc, char *argv[] ){ ... |
ここで、argc
にコマンドラインオプションの数(コマンド自体を
含む)、argv[]
にそれぞれの文字列へのポインタが入っている。
これを使う場合には通常以下のように行う。
main( int argc, char *argv[] ){ char *p; int i; for(i=0; i<argc; i++){ p=argv[i]; printf("argv[%d]= %s\n",i,p); } } |
つまり、このプログラムに対して、
> a.out test1 test2 test3 argv[0]= a.out argv[1]= test1 argv[2]= test2 argv[3]= test3 |
となる訳である。注意すべきは、コマンドラインの引数の数を越えてアクセス してはならない点である。
また、このようにコマンドラインを扱う場合には、多くのコマンドで コマンドオプションを扱うものが多い。例えば、 lsコマンドには 次のようなオプションもある。
> ls -l test/ |
この場合はいわゆるロングフォーマットで出力されるのだが、
プログラムする側から見た場合、オプション -l
と
test/
とを区別する必要がある。通常、オプションはそれを
示すために -
の後に指定するなどの方法をとるが、
それに対応して -
を特別扱いする事が必要となる。
以下のプログラムはこうしたオプションの-
がある場合の
処理の簡単な場合について対応したものだが、ここで対応しきれて
いないような問題もある。それは、-lF
のようなオプション
の指定方法をされた場合である。
main( int argc, char *argv[] ){ char *p, *target; int i; for(i=0; i<argc; i++){ p=argv[i]; if(*p=='-'){ /* オプションの引数 */ p++; switch(*p){ case 'l': /* -l の場合 */ break; case 'F': /* -F */ break; } }else{ /* オプションでない引数 */ target = p; } } |