次のプログラムを打ち込んで実行してみて下さい。
/* サンプル7-2 "sample7-2.c" --- 端末との入出力プログラム */
#include <stdio.h>
#include <stdlib.h>
struct info {
char name[256];
int age;
};
typedef struct info Info;
int main(void) {
/* 構造体"Info"を用意 */
Info information;
/* 名前データの入力 */
printf("input name>");
scanf("%s", information.name);
/* 年齢データの入力 */
printf("input age>");
scanf("%d", &(information.age));
/* 入力したデータの表示 */
printf("name: %s\n", information.name);
printf("age: %d\n", information.age);
return 0;
}
このプログラムについて、注意すべき点を幾つか挙げます。
構造体とは、複数の変数をまとめて扱えるようにしたものです。この例では、次の部分でinfo
という名前の構造体を定義しています。
struct info {
char name[256];
int age;
};
構造体の定義は、
struct 構造体の名前 {
まとめたい
変数を並べる
};
と書きます。従ってこのサンプルでは、char
の配列(文字列変数)name
とint
型変数age
をまとめた構造体info
が定義されています。
また、サンプルでは、typedef
でstruct info
という型にInfo
という別名をつけています。
typedef 型 別名
定義した構造体は、普通の変数のように宣言して使用します。サンプルでは、main()
関数の先頭で次のように宣言されています。
Info information;
これで、Info
型の構造体変数information
が使えるようになりました。構造体変数information
にまとめられている変数を使うには、
構造体変数名.変数名
と記述します。例えば、information
の中のage
に18を代入するには、
information.age = 18;
と書きます。
構造体info
に住所(char address[256];
)と郵便番号(int zip_code;
)を追加して下さい。住所と郵便番号も入力&表示できるようにして下さい。
/* 構造体の練習 */ #include <stdio.h> #include <stdlib.h> struct info { char name[256]; int age; char address[256]; int zip_code; }; typedef struct info Info; int main(void) { /* 構造体"Info"を用意 */ Info information; /* 名前データの入力 */ printf("input name> "); scanf("%[^\n]", information.name); /* 年齢データの入力 */ printf("input age> "); scanf("%d", &(information.age)); /* 住所データの入力 */ printf("input address> "); scanf("%[^\n]", information.address); /* 郵便番号データの入力 */ printf("input zip> "); scanf("%d", &(information.zip_code)); /* 入力したデータの表示 */ printf("name: %s\n", information.name); printf("age : %d\n", information.age); printf("addr: %s\n", information.address); printf("zip : %d\n", information.zip_code); return 0; }
サンプルプログラム中で入力データを格納していた構造体変数information
を配列にし、複数人のデータを扱えるようにして下さい。良く分からないという人は、以下のプログラムを参考にして下さい。
/* 課題7-2 "exercise7-2.c" --- 配列の練習 */
#include <stdio.h>
#include <stdlib.h>
struct info {
char name[256];
int age;
char address[256];
int zip_code;
};
typedef struct info Info;
int main(void) {
/* 構造体変数の配列を用意(3人分) */
Info information[3];
/* forループ用変数 */
int i;
/* 各種データの入力(3人分) */
for (i = 0; i < 3; i++) {
/* 名前の入力 */
printf("input name> ");
scanf("%s", information[i].name);
/* あとは自分で考えよう */
}
/*
* 入力したデータの表示(3人分)
* ここもforループで3回表示しよう
*/
return 0;
}
/* 課題7-2 "exercise7-2.c" --- 配列の練習 */ #include <stdio.h> struct info { char name[256]; int age; char address[256]; int zip_code; }; typedef struct info Info; int main(void) { /* 構造体変数の配列を用意(3人分) */ Info information[3]; /* forループ用変数 */ int i; /* 各種データの入力(3人分) */ for ( i=0; i < 3; i++ ) { /* 名前の入力 */ printf("input name>"); scanf("%[^\n]", information[i].name); /* 年齢データの入力 */ printf("input age>"); scanf("%d", &(information[i].age)); /* 住所データの入力 */ printf("input address>"); scanf("%[^\n]", information[i].address); /* 郵便番号データの入力 */ printf("input zipcode>"); scanf("%d", &(information[i].zip_code)); } /* 各種データの入力(3人分) */ for ( i=0; i < 3; i++ ) { printf("name[%d]: %s\n",i, information[i].name); printf("age[%d]: %d\n",i, information[i].age); printf("address[%d]: %s\n",i, information[i].address); printf("zip[%d]: %d\n",i, information[i].zip_code); } return 0; }
「おさらい」のファイル入出力プログラムを参考に、課題1のプログラムで入力したデータを ファイル「info.dat
」に保存するように変更して下さい。
ヒント
fopen(ファイル名, モード)
が必要ですね。printf
、をfprintf
にするとファイルに出力できる。fclose()
をお忘れなく。ファイル「info.dat
」の内容は、順に、
人数
名前, 年齢, 住所, 郵便番号
名前, 年齢, 住所, 郵便番号
...
となるようにして下さい。例えば、3人分情報を保存したデータファイルは、
3
SazaeSan, 36, Setagayaku, 158
Taiko, 32, Setagayaku, 158
Hanazawa, 14, Setagayaku, 158
となります。
/* 課題2ファイル出力 */ #include <stdio.h> #include <stdlib.h> struct info { char name[256]; int age; char address[256]; int zip_code; }; typedef struct info Info; int main(void) { /* 構造体変数の配列を用意(3人分) */ Info information[3]; /* forループ用変数 */ int i; /* ファイルポインタ */ FILE *fp; /* 各種データの入力(3人分) */ for ( i=0; i < 3; i++ ) { /* 名前の入力 */ printf("input name>"); scanf("%s", information[i].name); /* 年齢データの入力 */ printf("input age>"); scanf("%d", &(information[i].age)); /* 住所データの入力 */ printf("input address>"); scanf("%s", information[i].address); /* 郵便番号データの入力 */ printf("input zipcode>"); scanf("%d", &(information[i].zip_code)); } /* ファイルオープン */ if( (fp = fopen("info.dat", "w")) == NULL ){ printf(" *** file open error *** \n"); exit(1); } /* 1行目の書き込み */ fprintf (fp, "3\n"); /* データの書き込み */ for ( i=0; i < 3; i++ ) { fprintf(fp,"%s, ", information[i].name); fprintf(fp,"%d, ", information[i].age); fprintf(fp,"%s, ", information[i].address); fprintf(fp,"%d \n", information[i].zip_code); } /* ファイルクローズ */ fclose(fp); return 0; }
さて、最後にこのようなデータファイルを読み込むプログラムを作りましょう。 次のプログラムの不足部分を補って下さい。
scanf
の入力書式部分に 「%[^,]
」と書くと、",
"を入力するまでが1つの文字列 であると扱ってくれます。つまり、文字列の区切り文字を指定することができます。 「文字列, 数値, 文字列, 数値[改行]」という行を1つのfscanf
で読み込むには、 "%[^,], %d, %[^,], %d\n"
と書けば良いことにになります。 データの区切り","と改行"\n"
を忘れずに書くことが重要です。
/* 課題7-3 "exercise7-3.c" --- ファイルからのデータ読み込み */
#include <stdio.h>
#include <stdlib.h>
struct info {
char name[256];
int age;
char address[256];
int zip_code;
};
typedef struct info Info;
int main(void) {
/* 構造体変数の配列を用意(多めに100人分) */
Info information[100];
int num; /* 読み込み人数 */
int i; /* forループ用変数 */
FILE *fp; /* ファイルポインタ */
/*
* ここに
* ファイルポインタfpを使用して
* "info.dat"ファイルをオープン
* するプログラムを書いて下さい。
*/
/* 始めに人数を読み込む */
fscanf(fp, "%d\n", &num);
/* 人数が100を越えていたら終る */
if (num > 100) {
printf("Data for too many people!\n");
exit(1);
}
/* データの読み込み(人数分) */
for (i = 0; i < num; i++) {
fscanf(fp, "%[^,], %d, %[^,], %d\n",
information[i].name, &(information[i].age),
information[i].address, &(information[i].zip_code));
}
/*
* 入力したデータの表示(num人分)
*/
fclose(fp);
return 0;
}
/* 課題3ファイル入力 */ #include <stdio.h> #include <stdlib.h> struct info { char name[256]; int age; char address[256]; int zip_code; }; typedef struct info Info; int main(void) { /* 構造体"Info"を用意 */ Info information[3]; /* forループ用変数 */ int i, j; /* ファイルポインタ */ FILE *fp; /* ファイルを開いてデータを読み込む */ fp = fopen("info.dat", "r"); fscanf( fp, "%d\n", &j ); /* 人数をjに格納 */ for ( i=0; i < j; i++ ) /* 人数分、ループして読み込み */ { fscanf(fp, "%[^,], %d, %[^,], %d\n" , information[i].name, &(information[i].age) , information[i].address, &(information[i].zip_code)); } /* ファイルクローズ */ fclose(fp); /* 各種データの出力(j人分) */ for ( i=0; i < j; i++ ) { /* 入力したデータの表示 */ printf("name[%d]: %s\n",i, information[i].name); printf("age [%d]: %d\n",i, information[i].age); printf("addr[%d]: %s\n",i, information[i].address); printf("zip [%d]: %d\n",i, information[i].zip_code); } return 0; }
さて、時間が余った人は、このプログラムを基に、住所録プログラムを作って下さい。 携帯電話の電話帳のようなものです。最初にメニューが出てきて、住所一覧、住所登録、 住所削除の3つが選べるとします。この中からどれかを数字で選ぶと、それぞれの操作が できます。勿論、編集した住所はファイルに保存されるとします。