複数のカードを配列に格納する。カードには、名前やドライバーナンバーの他に、画像データを記憶させる。複数のカードから、必要なものを抽出した結果を別の配列に、リンクとして格納する。
画像データを格納するために、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