コマンドライン引数


引数

例えば、
% cp file1.txt file2.txt
のようにコマンドを実行するとき、file1.txt, file2.txtの ような引数を取ることがあるが、それをC言語で処理する方法がある。

(余談) なお、我々がよく実行する「./a.out」と、上の「cp」などのコマンドの間に 質的な違いはなく、どちらも実行ファイルである。cpコマンドの実体のありかは 「which cp」とすれば分かり、大抵は「/bin/cp」にある。 cpなどのコマンドが「./」を付けなくても実行できるのは、 ディレクトリ「/bin」が「パス」に登録されているため。パスは 「echo $PATH」などとすると見ることが出来る。

main関数の引数

今までmain関数は
int main(void)
{
    ...
    ...
}
のように書いていたが、引数を処理したい場合は
int main(int argc, char *argv[])
{
    ...
    ...
}
のように書く。

後者の書き方の場合、

が予めセットされた状態でプログラムがスタートする。 なお、argv[0]にはプログラム名がセットされることになっており、 実際の引数はargv[1]から始まる。 例えば、以下のプログラムをコンパイルし実行すると、

#include <stdio.h>

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

    for (i=0; i<argc; i++) {
        printf("%s\n", argv[i]);
    }

    return 0;
}
showargv.c

% ./showargv hoge fuga
./showargv
hoge
fuga
%
のようになる。

(余談)

これを使った、例えばcatコマンドとほぼ同じ動作をするプログラムは、 次の通り。

#include <stdio.h>

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

    for (i=1; i<argc; i++) {
        fp = fopen(argv[i], "r");
        if (fp == NULL) {
            fprintf(stderr, "%s: No such file or directory\n", argv[i]);
            continue;
        }
        while (1) {
            c = getc(fp);
            if (c == EOF) break;
            putchar(c);
        }
        fclose(fp);
    }

    return 0;
}
mycat.c

このように、UNIXのコマンドは非常に簡単なCのプログラムで作られているものも多い。

main関数の戻り値

main関数の戻り値は「int」である。 今まで、
int main(void)
{
    ...
    ...
    return 0;
}
のように無条件で0を返すようなプログラムを書いていた。

慣習として、 そのプログラムが正常に終了した場合は0、何か異常が 発生して正常に終了しなかった場合は0以外の値を返すことになっている。

int main(void)
{
    ...
    ...
    if (...) {
       fprintf(stderr, "error!\n");
       return 1;
    }
    ...
    ...
    return 0;
}
のような感じ。

(以下はあまり理解出来なくてもよい。CというよりはOSの使い方の問題なので。)

これにどんな意味があるかと言えば、 shell scriptの中でその値(終了コード)を利用することが出来る。 例えば、 error0.cerror1.cの2つを使って、

#! /bin/sh
./error0
echo $?
./error1
echo $?
のようなshell scriptを実行すると、
0
1
と表示され、$?で終了コードを参照できていることが分かる。
コマンドライン引数