はじめての C

C programming note*1
はじめに、オプションが 指定されたときの 解析用コードを つくっていきます。
ここでは、-f オプションに 続く コマンドライン上の ファイルを 開き、keyword を 読み込んでいます。

char *s;

key_n = -1;
while (--argc > 0 && **++argv == '-') {
for (s = *argv + 1; *s != '\0'; s++) {
switch (*s) {
case 'f':
if (--argc > 0) {
if )((fp = fopen(*++argv, "r"))( == NULL)
cant(*argv); /* no return */
else {
key_n = readkey(keyword, fp);
fclose(fp);
}
}
break;
default:
freekey(key_n, keyword);
usage(); /* no return */
}
}
}

以前 つくったものより 行数が 増えていますが、その ほとんどは ファイルの開閉に 関した 部分です。
readkey() は ファイルに 含まれる keyword の数を 返すので、その戻り値を key_n に 代入しておきます。
また、default で 関数 freekey() が 使われているのは、usage() を 実行すると プログラムは 終了してしまうので、その前に readkey() で 取得した メモリを 解放するためです。
次は、オプションが ついていないとき、
if (key_n == -1) {
if (argc < 0)
usage(); /* no return */
--argc;
keyword[0] = strdup(*argv++);
key_n = 1;
}
関数 strdup() を 使って コマンドライン上の 文字列 (キーワード) を ポインタ配列 keyword の 1つめに 記憶させ、key_n に '1' を 代入しています。
ここまでくれば、コマンドライン上に 残っているのは (普通は) 検索対象となる ファイル名だけですから、それほど むずかしくは ありません。
関数が find() に 変わることと、あとは、strdup() に malloc が 使われているので、freekey() を 使用して メモリを 解放しておくことだけです。
if (argc == 0)
find(stdin, keyword, key_n);
else {
while (argc--) {
if )((fp = fopen(*argv, "r"))( == NULL)
cant(*argv); /* no return */
find(fp, keyword, key_n);
fclose(fp);
argv++;
}
}
freekey(key_n, keyword);
これで 後は、プログラムを 組み立てるだけです。
その前に、課題にある機能を つけ加えるには どうすればよいか ? もう少しだけ 考えてみることに しましょう。
まず、追加する機能 1個に対し 1つの flag を プログラムの始めに おきます。
#define YES 1
#define NO 0

int x_flag = NO;

switch文に 追加する オプション名を 足し、その機能を 使うときには flag の値を 真に 変えるように します。
switch (*s) {
case 'x':
x_flag = YES;
break;
}
そして、関数 find() に、if文を 使って、flag が 真なら その機能を 実行する コードを 追加します。
if (x_flag == YES)
do_something();
追加する オプションは、次の 2つです。

1. 指定された 文字列が 「見つからなかった」 行だけを 出力する。

2. 指定された 文字列が 「見つかった」 行の番号 (そのファイルの中の 何行めか) を、行 そのものの 前に 出力できる (ようにする)。(p179)

<

*1:作ってわかる Cプログラミング」