% cp file1.txt file2.txtのようにコマンドを実行するとき、file1.txt, file2.txtの ような引数を取ることがあるが、それをC言語で処理する方法がある。
(余談) なお、我々がよく実行する「./a.out」と、上の「cp」などのコマンドの間に 質的な違いはなく、どちらも実行ファイルである。cpコマンドの実体のありかは 「which cp」とすれば分かり、大抵は「/bin/cp」にある。 cpなどのコマンドが「./」を付けなくても実行できるのは、 ディレクトリ「/bin」が「パス」に登録されているため。パスは 「echo $PATH」などとすると見ることが出来る。
int main(void)
{
...
...
}
のように書いていたが、引数を処理したい場合は
int main(int argc, char *argv[])
{
...
...
}
のように書く。
後者の書き方の場合、
#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 hoge fuga ./showargv hoge fuga %のようになる。
(余談)
#include <stdio.h>
int main(int argc, char *argv[])
{
while (*argv != NULL) {
printf("%s\n", *(argv++));
}
return 0;
}
|
これを使った、例えば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;
}
|
このように、UNIXのコマンドは非常に簡単なCのプログラムで作られているものも多い。
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.c、 error1.cの2つを使って、
#! /bin/sh ./error0 echo $? ./error1 echo $?のようなshell scriptを実行すると、
0 1と表示され、$?で終了コードを参照できていることが分かる。