第6回 ファイル操作(5月26日)

□ おしらせ

5月30日(金)は、休講です。6月2日(月)5限目に補講をします。

■ 今日のポイント

■ main 関数の引数

日頃より、Linux のコンソール上で、ワイルドカード「*(アスタリスクと読む)」を使用して複数のファイルを扱っているだろう。たとえば、以下のようにするとC言語のヘッダファイルだけを表示することができる。
# ls *.h
array2dint.h  mypicture.h  pgmimage.h

ワイルドカードから具体的なファイル名への変換は、コンソール側(シェル側)が処理してくれる。C言語のプログラム側では、変換後の具体的なファイル名を配列変数として受けとる。

例題1

次のプログラムを実行して、動作を確認してみよう。
/* list0601.c */
#include <stdio.h>
int main(int argc, char **argv)
{
  int i;

  for(i = 0; i < argc; i += 1 ){
    printf("%s\n", argv[i]);
  }
  return 0;
}
(実行例)
# gcc -Wall -o list0601 list0601.c
# ./list0601 ~/*

main 関数の第1引数は、配列変数 argv のサイズである。第2引数は、配列変数である。この配列変数は、1つの要素が char * の型であり、つまり、文字列である。argvは 0 番目から argc - 1 番目までが参照可能である。

argv[0] は、コマンドである。コンソールで入力したコマンドに、パスが付与されている。argv[1] 以降が、ワイルドカードの変換後のファイル名である。

練習1

F1選手の写真を格納したディレクトリから、名前と苗字のどちらか、または、両方に「A」が含まれている人物のファイル名を列挙するように、ワイルドカードを指定しよう。それを、list0601 を用いて動作確認をしよう。

たとえば、名前のどこかに「v」が含まれている人物は、「./list0601 ../lect03/PGM/*v*.pgm」を実行することで検索できる。ただし、「../lect03/PGM/」の部分は、各自の実行環境に合わせて変更せよ。これを実行すると、「09_David_Coulthard.pgm、19_Anthony_Davidson.pgm、23_Heikki_Kovalainen.pgm」が表示される。

■ 課題

(問1)namecard.c と namecard.h に、画像ファイルの名前が格納できるように、拡張をしよう。
ファイル名の変数名は自分で決めてよい。
その変数の型は、文字列へのポインタとせよ。
(問2)ファイル名の変数に対するアクセサを作成せよ。
ファイル名をその変数に代入する関数は、void nc_put_filename(NameCard *, char *); とせよ。代入時に文字列は、ポインタのコピーでよい。
ファイル名を参照する関数は、char *nc_get_filename(NameCard *); とせよ。
(問3)コンソール上で実行することを想定し、引数で指定されたファイルの数のぶんだけ NameCard の配列変数を準備し、それぞれにファイル名を格納せよ。そして、その配列の要素を参照してファイル名を表示せよ。そのプログラムを prac0601.c とする。
prac0601.c の main関数は、引数を2つとること
prac0601.c の main関数で用意する配列変数は ncarray という名前にすること。その型は NameCard へのポインタを要素とする配列としたいのだが、malloc により領域を確保するのに適切な型にせよ。つまり、ncarray = ( ??? ) malloc( sizeof( ??? ) * ??? ); という処理を行なうことを想定した型を宣言せよ。

実行の様子を以下に示す:
# make prac0601
gcc -Wall -O3 -c namecard.c
gcc -Wall -O3 -o prac0601 prac0601.c namecard.o
# ./prac0601 ../lect03/PGM/*b*.pgm
../lect03/PGM/04_Robert_Kubica.pgm
../lect03/PGM/07_Nico_Rosberg.pgm
../lect03/PGM/10_Mark_Webber.pgm
../lect03/PGM/14_Sebastien_Bourdais.pgm
../lect03/PGM/15_Sebastian_Vettel.pgm
../lect03/PGM/17_Rubens_Barrichello.pgm

■ 小レポート

上記課題を解決し、レポートに、namecard.h、namecard.c、prac0601.c および実行結果を掲載せよ。


(c) Masato TOKUHISA (2008, May 20.)