複数のカードを配列に格納する。カードには、名前やドライバーナンバーの他に、画像データを記憶させる。複数のカードから、必要なものを抽出した結果を別の配列に、リンクとして格納する。
画像データを格納するために、namecard.h と namecard.c を変更しよう。
まず、ネームカードの構造体を変更する:
typedef struct {
char name[NAME_LEN];
int age;
int number;
char *file;
Array2dInt *img;
} NameCard;
|
これに関連して、次の追加をしよう。
複数の画像ファイル名が、コマンドライン引数として与えられるものとする。このファイル名に基づき、ネームカードを生成する。同時に、画像ファイルもロードする。
(例) > ./a.out PGM/01_Kimi_Raikkonen.pgm PGM/02_Felipe_Massa.pgm PGM/03_Nick_Heidfeld.pgm PGM/04_Robert_Kubica.pgm |
上記のように実行したとき、main 関数では、4つの NameCard * で構成される配列変数を作成し、ドライバー名、ドライバー番号、画像ファイル名を格納し、画像データをロードする。
次に、特定のドライバーを抽出した結果を残すために、main 関数では、NameCard * の配列のインデクス番号(int)を要素とする配列変数を作る。
今回は、練習として、ドライバー番号が奇数の NameCard のインデクス番号を後者の配列変数に格納する。
(例)
int main( int argc, char **argv )
{
NameCard **ncarray, *nc;
int *result, i, j, num, sz;
char name[NAME_LEN], imgfile[10];
sz = argc - 1; // ドライバーの人数
ncarray = 引数のドライバーの人数ぶんだけ NameCard * を malloc
result = ncarray の配列番号 int を格納するための配列を malloc
// ncarray にロード ---------------------------------------
for( i = 1, j = 0; i < argc; i += 1, j += 1 ){
nc = nc_open();
ncarray[j] = nc;
argv[i] を解析し、ドライバー番号num, 名前 name を得る。
ネームカード nc に代入する。
画像ファイル名を nc に代入する。
画像ファイルをロードする。
}
// 抽出処理 ------------------------------------------------
for( i = 0, j = 0; i < size; i += 1 )
if( ncarray の i 番目のドライバー番号が奇数かどうか検査 )
result[j++] = i;
// 出力 ----------------------------------------------------
for( i = 0; i < j; i += 1 )
nc = ncarray[result[i]];
printf("%d\t%s\t[%s]\n",
nc_get_driver_number( nc ),
nc_get_name( nc ),
nc_get_filename( nc ));
snprintf( imgfile, 10, "tmp%d.pgm", nc_get_driver_number( nc ) );
nc_save_image( nc, imgfile );
}
return 0;
}
|
引数 argv の解析ルーチンの例
int scan_argument( char *line, int *num, char *name, int lmt )
{
char tmp[3], *p, *q;
int i, len;
// 末尾から「/」の手前までをファイル名として抽出する
len = strlen( line );
p = &line[len - 1];
for( ; len > 0; len -= 1, p -= 1 ){
if( *p == '/' ){
p += 1;
break;
}
}
// 数値部分を抽出する ------------------------------------
for( i = 0; i < 2; i += 1, p += 1 ) {
if( !isdigit(*p) )
return 0;
tmp[i] = *p;
}
if( *p != '_' )
return 0;
tmp[2] = '\0';
*num = atoi( tmp );
p += 1;
// 名前部分を抽出する(拡張子を含めない) ------------------
lmt -= 1;
for( i = 0, q = name; i < lmt; i += 1, p += 1, q += 1 )
if( *p == '\0' || *p == '.' )
break;
else if( *p == '_' )
*q = ' ';
else
*q = *p;
*q = '\0';
return 1;
}
|
2008.6.4 by tokuhisa