/****************************************************************************** ファイルからリストにデータを読み込む ファイル名はコマンドラインで指定する。ファイルは一行につきデータ一つであり、 文字列と数値の間はタブ(一つとは限らない)で区切られているとする。 ******************************************************************************/ #include #include #include #define OK 1 #define YES 1 #define NO 0 struct data { /* Data 型を定義 */ char *string; /* 文字列データ */ int number; /* 数値データ */ struct data *next; /* 次へのポインタ */ }; typedef struct data Data; /* struct data を Data と呼ぶ */ #define BUFSIZE 1024 /* バッファの大きさ */ int Data_add(Data *head, FILE *in); Data *Data_construct(FILE *in); void Data_printlist(Data *head); void Data_print(Data *p); int main(int argc, char *argv[]) { Data head; /* 先頭(ダミー) */ FILE *in; if (argc != 2) { fprintf(stderr, "引数の数が違います.\n"); return 1; } in = fopen(argv[1], "rt"); if (in == NULL) { fprintf(stderr, "ファイル \"%s\" を開けません.\n", argv[1]); return 1; } head.next = NULL; while (Data_add(&head, in) == OK) { ; } Data_printlist(&head); return 0; } /* in から一行を読み込んで Data を作り、ダミーのヘッド head の次に追加 */ int Data_add(Data *head, FILE *in) { Data *tmp; tmp = Data_construct(in); if (tmp == NULL) { return NO; } tmp->next = head->next; head->next = tmp; return OK; } /* in から一行を読み込んで Data 型オブジェクトを作り、そのアドレスを返す */ Data *Data_construct(FILE *in) { int j; Data *p; static char buf[BUFSIZE+1]; /* バッファ */ if ((p = malloc(sizeof(Data))) == NULL) { return NULL; } if (fgets(buf, BUFSIZE, in) == NULL) { free(p); return NULL; /* 読み込めなかった場合 */ } for (j=0; buf[j] != '\t'; j++) { /* タブをさがす */ ; } if ((p->string = malloc(j+1)) == NULL) { free(p); return NULL; } buf[j] = '\0'; strcpy(p->string, buf); /* 文字列をコピー */ while (buf[++j] == '\t') { /* タブをスキップ */ ; } p->number = atoi(buf+j); /* 数値データを読み込む */ /* next は初期化せず */ return p; } /* ダミーのヘッド head から始まるリストを印字 */ void Data_printlist(Data *head) { Data *p; for (p = head->next; p != NULL; p = p->next) { Data_print(p); } } /* Data 型オブジェクト *p を印字 */ void Data_print(Data *p) { printf("%s\t%d\n", p->string, p->number); }