次のプログラムを打ち込んで実行してみて下さい。
/* サンプル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つが選べるとします。この中からどれかを数字で選ぶと、それぞれの操作が できます。勿論、編集した住所はファイルに保存されるとします。