|
プログラムを実行すると永久ループします。
私の頭の中ではうまくできているのですが、一体どこが悪いのでしょうか?
回答のほどよろしくお願いいたします。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* ノード(レコード)の定義 */
typedef struct head{
char id; /* 'H' */
int ninzu; /* レコード件数 */
double goukei[3]; /* 科目別合計点数 */
}HEAD;
typedef struct body{
char id; /* 'B' */
char kumi[5]; /* クラス */
long int bango; /* 学籍番号(入学年(西暦)+連番(1-999)) */
char namae[20]; /* 名前 */
short int ten[3]; /* 科目別点数 */
}BODY;
typedef struct foot{
char id; /* 'E' */
}FOOT;
typedef union record{
struct head h_data; /* ヘッダー */
struct body b_data; /* 明細データ */
struct foot f_data; /* フッター */
}RECORD;
FILE *fp; /* ファイルポインタ の宣言(グローバル宣言) */
void file_header_update(BODY);
void file_data_write(BODY);
void file_display(void);
void main(int argc, char **argv)
{
BODY data;
RECORD rec;
int i;
if (argc != 2){
printf("コマンドライン引数に誤りがあります。\n");
printf("Usage:EXEname filename\n");
exit(EXIT_FAILURE);
}
/* ファイルオープン */
if ( (fp = fopen(argv[1],"r+b")) == NULL){
/*ファイルが存在しない場合は作成する*/
fp = fopen(argv[1],"w+b");
/*ヘッダーレコード作成*/
rec.h_data.id = 'H';
rec.h_data.ninzu = 0;
rec.h_data.goukei[0] = 0;
rec.h_data.goukei[1] = 0;
rec.h_data.goukei[2] = 0;
/*ヘッダーレコード書込*/
fseek(fp,0,SEEK_SET);
fwrite(&rec.h_data,sizeof(RECORD),1,fp);
}
while (printf("クラスを入力して下さい(CTRL+Z:終了)→"), gets(data.kumi) != NULL){
/* データ入力 */
printf("学籍番号を入力して下さい→");
scanf("%ld",&data.bango);
rewind(stdin); /* キーボードバッファクリア */
printf("名前を入力して下さい→");
gets(data.namae);
printf("科目別得点を入力して下さい(得点1 得点2 得点3)→");
scanf("%d %d %d",&data.ten[0],&data.ten[1],&data.ten[2]);
rewind(stdin); /* キーボードバッファクリア */
/* 明細レコード出力 */
file_data_write(data);
/* ヘッダーレコード更新 */
file_header_update(data);
}
/*フッターレコード作成*/
rec.f_data.id = 'E';
/*フッターレコード書込*/
fseek(fp,0,SEEK_END);
fwrite(&rec,sizeof(RECORD),1,fp);
/*ファイル内容表示*/
file_display();
/* ファイルクローズ */
fclose(fp);
}
/*
* ヘッダーレコードの更新関数
*/
void file_header_update(BODY data)
{
RECORD rec;
int i;
/* 先頭(ヘッダー)レコードの読込 */
fseek(fp,0,SEEK_SET); /* ファイルの先頭へ */
if (fread(&rec,sizeof(RECORD),1,fp) != 1){
printf("ヘッダーレコード読込失敗!\n");
exit(EXIT_FAILURE);
}
/* ヘッダー情報の更新 */
while(fread(&rec, sizeof(RECORD),1,fp),
data.namae != rec.b_data.namae){
data.ten[0] += rec.b_data.ten[0];
data.ten[1] += rec.b_data.ten[1];
data.ten[2] += rec.b_data.ten[2];
}
fseek(fp,0,SEEK_SET); /* ファイルの先頭へ */
if (fread(&rec,sizeof(RECORD),1,fp) != 1){
printf("ヘッダーレコード読込失敗!\n");
exit(EXIT_FAILURE);
}
rec.h_data.ninzu++;
rec.h_data.goukei[0] = data.ten[0];
rec.h_data.goukei[1] = data.ten[1];
rec.h_data.goukei[2] = data.ten[2];
/*ヘッダーレコード書込*/
if (fwrite(&rec,sizeof(RECORD),1,fp) != 1){
printf("ヘッダーレコード読込失敗!\n");
exit(EXIT_FAILURE);
}
}
/*
* 明細レコードの出力関数
*/
void file_data_write(BODY data)
{
RECORD rec;
int i;
long int putptr;
/* 最終レコードの読込 */
fseek(fp,(-1)*sizeof(RECORD),SEEK_END); /* 最終レコードへ */
if (fread(&rec,sizeof(RECORD),1,fp) != 1){
printf("最終レコード読込失敗!\n");
exit(EXIT_FAILURE);
}
if(rec.f_data.id == 'E'){
fseek(fp,(-1)*sizeof(RECORD),SEEK_END);
}
else{
fseek(fp,0,SEEK_END);
}
fwrite(&data,sizeof(RECORD),1,fp);
}
/*
* ファイルの内容表示関数
*/
void file_display(void)
{
RECORD rec;
int i;
printf("%4s %8s %-20s %5s %5s %5s\n", "クラス", "学籍番号", "名 前", "科目1", "科目2", "科目3");
/* 明細レコードの1件目読込 */
fseek(fp,0,SEEK_SET); /* ファイルの先頭へ */
if (fread(&rec,sizeof(RECORD),1,fp) != 1){
printf("ヘッダーレコード読込失敗!\n");
exit(EXIT_FAILURE);
}
/* 先頭データが最終レコードでなければレコードの内容を表示 */
while (fread(&rec, sizeof(RECORD), 1, fp), rec.b_data.namae != "E"){
/* データの表示 */
printf("%4s %8d %-20s %5d %5d %5d",rec.b_data.kumi, rec.b_data.bango, rec.b_data.namae, rec.b_data.ten[0], rec.b_data.ten[1], rec.b_data.ten[2] );
printf("\n");
/* 次レコードの読込 */
}
/* 先頭(ヘッダー)レコードの読込 */
fseek(fp,0,SEEK_SET); /* ファイルの先頭へ */
if (fread(&rec,sizeof(RECORD),1,fp) != 1){
printf("ヘッダーレコード読込失敗!\n");
exit(EXIT_FAILURE);
}
/* 合計の表示 */
printf(" %f %f %f",rec.h_data.goukei[0], rec.h_data.goukei[1], rec.h_data.goukei[2]);
printf("\n");
}
|