/* * union-rw2.c * 第1引数が "save" ならデータファイルの作成、 * 第2引数が "2" ならバージョン2のデータファイルの作成 * それ以外ならロード */ #include #include #include #define DATAFILE "memslot.bin" #define BUFSZ 20 typedef struct { char name[20]; int shusseki; int mathpt; int engpt; } TOKUTEN; typedef struct { char name[20]; int shusseki; int mathpt; int engpt; int japt; /* 国語の得点新設 */ } TOKUTEN2; typedef struct { char version[4]; union { TOKUTEN me; /* 数学と英語用の構造体 */ TOKUTEN2 mej; /* 数学と英語と国語用の構造体 */ }; } TKDATA; /* * TKDATA* のデータを出力する。 */ void dispdata(TKDATA *td) { TOKUTEN *d = &td->me; printf("%10.10s の得点 |\n", d->name); printf("%17.17s | %3d\n", "数学", d->mathpt); printf("%17.17s | %3d\n", "英語", d->engpt); if (0 == strcmp(td->version, "v2")) { printf("%17.17s | %3d\n", "国語", td->mej.japt); } } /* * TKDATA* のデータを所定のデータファイルにバイナリのまま書き込む */ int save(TKDATA *td) { TOKUTEN2 *t = &td->mej; char tmp[sizeof(t->name)+1]; FILE *fp; while (t->name[0] == '\0') { /* データの入力と構造体への代入 */ fputs("名前: ", stderr); fgets(tmp, sizeof tmp, stdin); sscanf(tmp, "%s", t->name); fputs("出席番号: ", stderr); fgets(tmp, sizeof tmp, stdin); t->shusseki = atoi(tmp); fputs("数学得点: ", stderr); fgets(tmp, sizeof tmp, stdin); t->mathpt = atoi(tmp); fputs("英語得点: ", stderr); fgets(tmp, sizeof tmp, stdin); t->engpt = atoi(tmp); if (strcmp(td->version, "v2") == 0) { fputs("国語得点: ", stderr); fgets(tmp, sizeof tmp, stdin); t->japt = atoi(tmp); } } fputs("これから保存するデータ:\n", stderr); dispdata(td); if (NULL != (fp=fopen(DATAFILE, "w"))) { /* ここで実際にファイルに書き込んでいる */ fwrite(td, sizeof *td, 1, fp); fclose(fp); fprintf(stderr, "%s に書き込み完了\n", DATAFILE); return 0; } return 1; } /* * 所定のデータファイルのバイナリデータを TKDATA* に読み込む */ int load(TKDATA *td) { FILE *rfp; int sz = sizeof *td; int rc=1; if (NULL != (rfp=fopen(DATAFILE, "r"))) { /* freadでバイナリデータを読む */ if (1 == fread(td, sz, 1, rfp)) { printf("%sからロードしたデータ(%s):\n", DATAFILE, td->version); dispdata(td); rc = 0; } else { fputs("読み込み失敗\n", stderr); } } fclose(rfp); return rc; } int main(int argc, char *argv[]) { int rc; TKDATA tkdata; memset(&tkdata, 0, sizeof tkdata); if (argc > 1 && 0 == strcmp(argv[1], "save")) { if (argc > 2 && 0 == strcmp(argv[2], "2")) strncpy(tkdata.version, "v2", sizeof tkdata.version); else strncpy(tkdata.version, "v1", sizeof tkdata.version); rc = save(&tkdata); } else rc = load(&tkdata); return rc; }