ファイル読み書きについて(再)
Posted: 2016年5月24日(火) 16:21
////////////////////////
// //
// ヘッダファイル //
// //
////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//////////////////////
// //
// 構造体の定義 //
// //
//////////////////////
typedef enum
{
MODE_FINISH = 0 , // 終了
MODE_INPUT , // 入力
MODE_OUTPUT , // 出力
MODE_SAVE , // セーブ
MODE_LOAD , // ロード
MODE_MAX , // 最大数
}MODE;
typedef struct
{
char aName[256]; // 名前
int nAge; // 年齢
float fHeight; // 身長
float fWeight; // 体重
}PersonalData;
///////////////////////////
// //
// プロトタイプ宣言 //
// //
///////////////////////////
void SelectMode ( void );
int Input ( PersonalData* pData );
void Output ( PersonalData* pData , int nNumHuman );
void Save ( PersonalData* pData , int nNumHuman );
void Load ( PersonalData* pData , int* nNumHuman );
////////////////////
// //
// マクロ定義 //
// //
////////////////////
#define MinCount (1)
#define MaxCount (5)
////////////////////
// //
// メイン関数 //
// //
////////////////////
void main ( void )
{
// モード選択
SelectMode ();
// キー入力待ち
rewind (stdin);
getchar();
return;
}
void SelectMode ( void )
{
PersonalData aData[MaxCount];
int nNumHuman;
memset ( aData , 0 , sizeof ( aData ) );
MODE mode;
do
{
// 番号入力
printf ( "\nMENU\n" );
printf ( "以下の番号から処理を選んでください\n" );
printf ( "1. 入力\n" );
printf ( "2. 出力\n" );
printf ( "3. セーブ\n" );
printf ( "4. ロード\n" );
printf ( "0. 終了\n" );
printf ( "> " );
scanf ( "%d" , &mode );
// 各番号の処理
switch ( mode )
{
// 終了処理
case 0:
printf ( "プログラムを終了します\n" );
break;
// 入力処理
case 1:
nNumHuman = Input ( &aData[0] );
break;
// 出力処理
case 2:
Output ( &aData[0] , nNumHuman );
break;
// セーブ処理
case 3:
Save ( &aData[0] , nNumHuman );
break;
// ロード処理
case 4:
Load ( &aData[0] , &nNumHuman );
break;
}
}while ( mode != MODE_FINISH ); // 終了処理が呼ばれるまでループ
}
//////////////////
// //
// 入力関数 //
// //
//////////////////
int Input ( PersonalData* pData )
{
int Name_Count;
int nNumHuman;
if ( pData == NULL )
{
printf ( "データ入力に失敗しました\n" );
return 0;
}
do
{
printf ( " 何人分のデータを入力しますか?(%d~%d人) > " , MinCount , MaxCount );
scanf ( "%d" , &nNumHuman );
}while ( nNumHuman < MinCount | nNumHuman > MaxCount );
printf ( "\n %d人分のデータを入力します\n" , nNumHuman );
// 人数分入力
for ( int InputNum = 1; InputNum <= nNumHuman; InputNum++ )
{
printf ( " %d人目のデータ入力 \n" , InputNum );
printf ( " 姓(全角5文字以内) > " ); // 苗字入力
scanf ( "%s" , &pData -> aName[0] );
Name_Count = strlen ( &pData -> aName[0] );
printf ( " 名(全角5文字以内) > " ); // 名前入力
scanf ( "%s" , &pData -> aName[Name_Count] );
printf ( " 年齢(半角2ケタ) > " ); // 年齢入力
scanf ( "%d" , &pData -> nAge );
printf ( " 身長(cm) (半角数字・少数第1位まで) > " ); // 身長入力
scanf ( "%f" , &pData -> fHeight );
printf ( " 体重(kg) (半角数字・少数第1位まで) > " ); // 体重入力
scanf ( "%f" , &pData -> fWeight );
pData++;
}
return nNumHuman;
}
////////////////////
// //
// セーブ関数 //
// //
////////////////////
void Save ( PersonalData* pData , int nNumHuman )
{
FILE* fp;
if ( nNumHuman < MinCount | nNumHuman > MaxCount ) // エラーの原因がすぐわかる
{
printf ( "データがありません\n" );
return;
}
if ( pData != NULL )
{
// ファイルを開く
fp = fopen ( "savedata.bin", "wb" );
if ( fp == NULL )
{
printf ( "FILE OPEN ERROR\n" );
rewind ( stdin );
getchar ();
}
else
{
// ファイル書き込み
fwrite ( &nNumHuman , sizeof ( int ) , 1 , fp );
fwrite ( pData , sizeof ( pData ) , nNumHuman , fp );
// ファイルを閉じる
fclose ( fp );
}
if ( fclose ( fp ) != EOF )
{
printf ( "FILE CLOSE ERROR" \n );
rewind ( stdin );
getchar ();
}
else
{
printf ( "\nセーブしました\n" );
rewind ( stdin );
getchar ();
}
}
else
{
printf ( "セーブ失敗\n" );
rewind ( stdin );
getchar ();
}
}
////////////////////
// //
// ロード関数 //
// //
////////////////////
void Load ( PersonalData* pData , int* nNumHuman )
{
FILE* fp;
// ファイルを開く
fp = fopen ( "savedata.bin" , "rb" );
if ( fp == NULL )
{
printf ( "FILE OPEN ERROR\n" );
rewind ( stdin );
getchar ();
}
else
{
if ( pData != NULL )
{
if ( nNumHuman < MinCount | nNumHuman > MaxCount )
{
printf ( "データがありません\n" );
rewind ( stdin );
getchar ();
}
else
{
// ファイル読み込み
fread ( nNumHuman , sizeof ( int ) , 1 , fp );
fread ( pData , sizeof ( *pData ) , *nNumHuman , fp );
// ファイルを閉じる
fclose ( fp );
printf ( "ロードしました\n" );
rewind ( stdin );
getchar ();
}
}
else
{
printf ( "データがありません\n" );
rewind ( stdin );
getchar ();
}
}
}
//////////////////
// //
// 出力関数 //
// //
//////////////////
void Output ( PersonalData* pData , int nNumHuman )
{
if ( nNumHuman == 0 )
{
printf ( "データがありません\n" );
return;
}
if ( pData == NULL )
{
printf ( "出力に失敗しました\n" );
return;
}
// 人数分出力
for ( int nCount_2 = 0; nCount_2 < nNumHuman; nCount_2++ )
{
printf ( " %d人目のデータ出力 \n" , nCount_2 + 1 );
printf ( " 姓名 : %s\n" , pData -> aName[0] ); // 姓名出力
printf ( "年齢 : %d 才\n" , pData -> nAge ); // 年齢出力
printf ( "身長: %1.0f cm\n" , pData -> fHeight ); // 身長出力
printf ( " 体重: %1.0f kg\n" , pData -> fWeight ); // 体重出力
pData++;
}
}
/////////////// EOF ///////////////
そこで、一つ問題が発生したのですが、一回目のデータをセーブしてからウィンドウを閉じて、再び開き、ロードして出力すると名前以外が変に出力されます。
どこがおかしいのでしょうか?