わからなくて困ってます

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
SZ-TS

わからなくて困ってます

#1

投稿記事 by SZ-TS » 9年前

キャラの人数、ステータスをそれぞれ自由に入力し、それらをバイナリでセーブ、ロードしたいのですが、fwrite・freadの()の中の書き方がよくわかりません。
教えていただけるとありがたいです。

typedef struct
{
int Gender;
char Name[50];
int HitPoint;
int Attack;
int Diffence;
int Speed;
}NINGEN;

NINGEN nakama[5];
NINGEN *pnakama;
int main(void)
{
char Name[50];
int Gender;
int HitPoint;
int Attack;
int Diffence;
int Speed;

int no;
int yes_no;
int count;
int Num_Max;

printf("仲間のデータをロードしますか? Yes:1 No:2 \n⇒");
scanf("%d",&yes_no);
if(yes_no==1)
{
FILE*fp;
if( (fp=fopen("Save.dat","rb") )==NULL)
{
printf("ファイルがありません \n");
}
else
{
fread(&Name, sizeof(char), 1, fp);
fread(&Gender, sizeof(Gender), 1, fp);
fread(&HitPoint, sizeof(HitPoint), 1, fp);
fread(&Attack, sizeof(Attack), 1, fp);
fread(&Diffence, sizeof(Diffence), 1, fp);
fread(&Speed, sizeof(Speed), 1, fp);
fclose(fp);

pnakama=nakama;

printf("性別は?⇒");
scanf("%s", &(pnakama+count)->Gender);

printf("名前は?⇒");
scanf("%s", &(pnakama+count)->Name[0]);

printf("HPは?⇒");
scanf("%d", &(pnakama+count)->HitPoint);

printf("攻撃力は?⇒");
scanf("%d", &(nakama+count)->Attack);

printf("防御力は?⇒");
scanf("%d", &(pnakama+count)->Diffence);

printf("素早さは?⇒");
scanf("%d", &(pnakama+count)->Speed);

rewind(stdin);
getchar();

return 0;
}
}
else
{
printf("ロードしませんでした \n");
}

///***** キャラの人数、ステータスを入力、表示(今回は省略) *****///

printf("データをセーブしますか? Yes:1 No:2 \n⇒");
scanf("%d", &yes_no);
if(yes_no==1)
{
FILE*fp;
if((fp=fopen("Save.dat","wb") )==NULL)
{
printf("セーブできませんでした \n");
}
else
{
fwrite(&Name, sizeof(char), Num_Max, fp);
fwrite(&Gender, sizeof(Gender), Num_Max, fp);
fwrite(&HitPoint, sizeof(HitPoint), Num_Max, fp);
fwrite(&Attack, sizeof(Attack), Num_Max, fp);
fwrite(&Diffence, sizeof(Diffence), Num_Max, fp);
fwrite(&Speed, sizeof(Speed), Num_Max, fp);
fclose(fp);

printf("セーブしました \n");

rewind(stdin);
getchar();
}
else
{
printf("セーブしませんでした \n");

rewind(stdin);
getchar();
}
return 0;
}

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: わからなくて困ってます

#2

投稿記事 by みけCAT » 9年前

ソースコードを提示する際は、BBCodeを有効にした(無効にしない)状態でcodeタグで囲んでいただけると、見やすくてありがたいです。
SZ-TS さんが書きました:fwrite・freadの()の中の書き方がよくわかりません。
教えていただけるとありがたいです。
Man page of FREAD (fwriteの解説もあります)
オフトピック
データを読み込んだ後それを全く使わずに未初期化で不定の値のcountを使った危険な処理をし、セーブは未初期化で不定の値を保存…
fwrite・fread以前の問題のような気がします。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: わからなくて困ってます

#3

投稿記事 by みけCAT » 9年前

オフトピック
というか、他の変数は読み書きの時に変数名をsizeofのオペランドにしているのに、
なんでよりによってNameだけわざわざ型名をsizeofのオペランドにして、しかも不自然なんだろう…?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

かずま

Re: わからなくて困ってます

#4

投稿記事 by かずま » 9年前

このプログラムは参考になりますか?
これを元にあなたのプログラムを書いて、ここに提示してから解決にしてください。

コード:

#include <stdio.h>

#define MAX_MEMBERS 5

typedef struct
{    
     char name[40];
     int age;
} Person;

Person members[MAX_MEMBERS];
int num_members;

void display()
{
    int i;
    if (num_members == 0) {
        printf("no members\n");
        return;
    }
    for (i = 0; i < num_members; i++) {
        Person *p = &members[i];
        printf("[%d]\n  名前: %s\n  年齢: %d\n", i+1, p->name, p->age);
    }
}

void add()
{
    Person *p;
    if (num_members == MAX_MEMBERS) {
        printf("sorry! full\n");
        return ;
    }
    p = &members[num_members];
    printf("名前: ");
    if (scanf("%s", p->name) != 1) return;
    printf("年齢: ");
    if (scanf("%d", &p->age) != 1) return;
    num_members++;
}

void save()
{
    FILE *fp = fopen("save.dat", "wb");
    if (!fp) {
        printf("save failed\n");
        return;
    }
    fwrite(members, sizeof(Person), num_members, fp);
    fclose(fp);
    printf("  save completed\n");
}

void load()
{
    int n;
    FILE *fp = fopen("save.dat", "rb");
    if (!fp) {
        printf("load failed\n");
        return;
    }
    num_members = fread(members, sizeof(Person), MAX_MEMBERS, fp);
    fclose(fp);
    printf("  %d members\n", num_members);
}

int main(void)
{    
    while (1) {
        int n;
        while (1) {
            printf("\n"
                "  1. display members\n"
                "  2. add a member\n"
                "  3. save members\n"
                "  4. load members\n"
                "  5. quit\n"
                "> ");
            if (scanf("%d", &n) == 1 && n >= 1 && n <= 5) break;
            if (feof(stdin)) return 0;
            while (getchar() != '\n') ;
        }
        if (n == 1) display();
        else if (n == 2) add();
        else if (n == 3) save();
        else if (n == 4) load();
        else break;
    }
    return 0;
}

SZ-TS

なんどもすみません

#5

投稿記事 by SZ-TS » 9年前

コード:

#include<stdio.h>
#include<stdlib.h>

#define MAX_MEMBERS 5

typedef struct
{
	 char Name[50];
	 int HitPoint;
	 int Attack;
	 int Diffence;
	 int Speed;
} NINGEN;

NINGEN members[MAX_MEMBERS];

int num_members;
int count;

void Display()
{
	 if(num_members==0)
	 {
		  printf("データがありません");
		  return;
	 }

	 for(count=0; count<num_members; count++)
	 {
		  NINGEN*p=&members[count];

		  printf("名前は%s \n", count+1, p->Name);

		  printf("HPは%d \n", count+1, p->HitPoint);

		  printf("攻撃力は%d \n", count+1, p->Attack);

		  printf("防御力は%d \n", count+1, p->Diffence);

		  printf("素早さは%d \n\n", count+1, p->Speed);

	      rewind(stdin);
	      getchar();
	 }
}

void Add()
{
	 NINGEN*p;
	 if(num_members==MAX_MEMBERS)
	 {
		  printf("仲間がいっぱいでこれ以上増やせない! \n");
		  return;
	 }
		  printf("仲間(5人まで)は何人? \n");
	      scanf("%d", &num_members);

	      printf("=====仲間のステータスを入力してください===== \n");

		  p=&members[num_members];

		       printf("名前は?⇒");
		       if(scanf("%s", p->Name)!=1)return;

		       printf("HPは?⇒");
		       if(scanf("%d", p->HitPoint)!=1)return;

      	       printf("攻撃力は?⇒");
		       if(scanf("%d", p->Attack)!=1)return;

		       printf("防御力は?⇒");
		       if(scanf("%d", p->Diffence)!=1)return;

		       printf("素早さは?⇒");
		       if(scanf("%d", p->Speed)!=1)return;

			   num_members++;
		  

	      rewind(stdin);
	      getchar();
}

void Save()
{
	 FILE*fp;
	 if((fp=fopen("Save.dat","wb") )==NULL)
	 {        
		  printf("セーブできませんでした \n");
		  return;
	 }
	 fwrite(members,sizeof(NINGEN),num_members,fp);
	 fclose(fp);

	 printf("仲間のステータスをセーブしました! \n");
}

void Load()
{
	 FILE*fp;
	 if( (fp=fopen("Save.dat","rb") )==NULL)
	 {
		  printf("データがありません! \n");
		  return;
	 }
	 num_members=fread(members,sizeof(NINGEN),MAX_MEMBERS,fp);
	 fclose(fp);

	 printf("仲間は%d人です \n", num_members);

	 printf("名前は%s \n", num_members);

	 printf("HPは%d \n", num_members);

     printf("攻撃力は%d \n", num_members);

	 printf("防御力は%d \n", num_members);

	 printf("素早さは%d \n\n", num_members);
}

int main(void)
{
    while (1) 
	{    
         int n;
         while (1)
		 {    
              printf("\n" " 1. データ出力 \n" " 2. データ入力 \n" " 3. データセーブ \n" " 4. データロード \n" " 5. 終了 \n" "⇒");
              if (scanf("%d", &n) == 1 && n >= 1 && n <= 5) 
				  break;
              if (feof(stdin)) 
				  return 0;
              while (getchar() != '\n');
		 }
         if (n == 1) Display();
         else if (n == 2) Add();
         else if (n == 3) Save();
         else if (n == 4) Load();
         else break;
	}
	return 0;
}
ソースコードのサンプルありがとうございます。
ステータスを一回で複数入力させたいのですが、その場合は
if(scanf("%s", p->Name)!=1)return;
の1の部分を変えればいいんでしょうか?

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: なんどもすみません

#6

投稿記事 by みけCAT » 9年前

SZ-TS さんが書きました:ステータスを一回で複数入力させたいのですが、その場合は
if(scanf("%s", p->Name)!=1)return;
の1の部分を変えればいいんでしょうか?
いいえ。「一回で複数入力」の定義がよくわからないですが、書式文字列を変えるか、その他の部分を変える必要がありそうです。

それ以前の問題として、scanfやprintfに型が違う誤ったデータを渡していて、undefined behaviorになる部分が大量に存在します。
テストを行ってください。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

SZ-TS

Re: わからなくて困ってます

#7

投稿記事 by SZ-TS » 9年前

コード:

#include <stdio.h>
 
#define MAX_MEMBERS 5
 
typedef struct
{    
     char name[40];
     int Hp;
	 int Attack;
	 int Diffence;
	 int Speed;
} NINGEN;
 
NINGEN members[MAX_MEMBERS];
int num_members;
 
void Display()
{
    int count;
    if (num_members == 0) 
	{    
         printf("データがありません! \n");
         return;
    }
    for (count = 0; count < num_members; count++) 
	{     
         NINGEN *p = &members[count];
         printf("[%d]\n  名前: %s \n  HitPoint: %d \n  攻撃力:%d \n  防御力:%d \n  素早さ:%d \n", count+1, p->name, p->Hp, p->Attack, p->Diffence, p->Speed);
    }
}
 
void Add()
{     
     NINGEN *p;
     if (num_members == MAX_MEMBERS) 
	 {    
          printf("これ以上仲間にできない! \n");
          return ;
     }
     p = &members[num_members];
     printf("名前: ");
     if (scanf("%s", p->name) != 1) return;
     printf("HitPoint: ");
     if (scanf("%d", &p->Hp) != 1) return;
	 printf("攻撃力:");
	 if (scanf("%d", &p->Attack) != 1) return;
	 printf("防御力:");
	 if (scanf("%d", &p->Diffence) != 1) return;
	 printf("素早さ:");
	 if (scanf("%d", &p->Speed) != 1) return;
     num_members++;
}
 
void Save()
{    
     FILE *fp = fopen("save.dat", "wb");
     if (!fp) 
	 {    
          printf("save failed\n");
          return;
     }
     fwrite(members, sizeof(NINGEN), num_members, fp);
     fclose(fp);
     printf("セーブしました! \n");
}
 
void Load()
{    
     int n;
     FILE *fp = fopen("save.dat", "rb");
     if (!fp) 
	 {    
          printf("データがありません! \n");
          return;
     }
     num_members = fread(members, sizeof(NINGEN), MAX_MEMBERS, fp);
     fclose(fp);
     printf(" %d members\n ", num_members);
}
 
int main(void)
{        
     while (1) 
	 {    
          int n;
          while (1) 
		  {    
               printf("\n"  "  1. ステータス表示 \n"  "  2. 仲間を増やす! \n"  "  3. データセーブ \n"  "  4. データロード \n"  "  5. 終了 \n"  "> ");
               if (scanf("%d", &n) == 1 && n >= 1 && n <= 5) 
			   break;
               if (feof(stdin) ) 
			   return 0;
               while (getchar() !='\n');
          }
          if (n == 1) Display();
          else if (n == 2) Add();
          else if (n == 3) Save();
          else if (n == 4) Load();
          else break;
	 }
      return 0;
}
言葉足らずですみません。
「仲間は何人ですか?」というふうに仲間を増やす選択(void Add())のところで聞いて、scanfで入力された人数分のステータスをまとめて入力させたいという意味です。
例.
仲間は何人ですか?(5人まで)→2人
1人目のステータスを入力
2人目のステータスを入力
最初の選択画面表示に戻る

かずま

Re: わからなくて困ってます

#8

投稿記事 by かずま » 9年前

SZ-TS さんが書きました: 「仲間は何人ですか?」というふうに仲間を増やす選択(void Add())のところで聞いて、scanfで入力された人数分のステータスをまとめて入力させたいという意味です。
例.
仲間は何人ですか?(5人まで)→2人
1人目のステータスを入力
2人目のステータスを入力
最初の選択画面表示に戻る
その通りにコーディングするだけですね。

コード:

void Add()
{     
    int n, i;
    NINGEN *p;
    if (num_members == MAX_MEMBERS) {
        printf("これ以上仲間にできない! \n"); return;
    }
    while (1) {
        int r = MAX_MEMBERS - num_members;
        printf("仲間は何人ですか?(%d人まで): ", r);
         if (scanf("%d", &n) == 1 && n >= 0 && n <= r) break;
        if (feof(stdin)) return;
        while (getchar() != '\n') ;
    }
    for (i = 0; i < n; i++) {
        p = &members[num_members];
        printf("%d人目のステータスを入力\n", num_members + 1);
        printf("  名前: ");  if (scanf("%s", p->name) != 1)    return;
        printf("  HitPoint: "); if (scanf("%d", &p->Hp) != 1)  return;
        printf("  攻撃力:"); if (scanf("%d", &p->Attack) != 1) return;
        printf("  防御力:"); if (scanf("%d", &p->Diffence) != 1) return;
        printf("  素早さ:"); if (scanf("%d", &p->Speed) != 1)  return;
        num_members++;
    }
}

SZ-TS

Re: わからなくて困ってます

#9

投稿記事 by SZ-TS » 9年前

コード:

#include <stdio.h>
#define MAX_MEMBERS 5
 
typedef struct
{    
     char name[40];
     int Hp;
	 int Attack;
	 int Diffence;
	 int Speed;
} NINGEN;
 
NINGEN members[MAX_MEMBERS];
int num_members;
int count;

void Display()
{
	 
    if (num_members == 0) 
	{    
         printf("データがありません! \n");

		 rewind(stdin);
		 getchar();

         return;
    }
	printf("====仲間のステータスを表示します==== \n");

	rewind(stdin);
	getchar();

    for (count = 0; count < num_members; count++) 
	{  
		 NINGEN *p = &members[count];

         printf(" [%d]\n    名前: %s \n    HitPoint: %d \n    攻撃力:%d \n    防御力:%d \n    素早さ:%d \n", count+1, p->name, p->Hp, p->Attack, p->Diffence, p->Speed);
    }
	rewind(stdin);
	getchar();

	return;
}
 
void Add()
{     
     NINGEN *p;
     if (num_members == MAX_MEMBERS) 
	 {    
          printf("これ以上仲間にできない! \n");

		  rewind(stdin);
		  getchar();

          return ;
     }
	 while(1)
	 {
		  int n = MAX_MEMBERS - num_members;
		  printf("仲間は何人ですか?(%d人まで)⇒",n);
		  if(scanf("%d", &num_members) ==1 && num_members >=0 && num_members<=n )break;
		  if(feof(stdin) ) return;
		  while(getchar() !='\n');
	 }
	 for(count=0; count<num_members; count++)
	 {
     p = &members[num_members];

	 printf("=====仲間のステータスを入力してください===== \n");
	 printf("%d人目のステータス \n", num_members+1);
     printf("名前: ");
     if (scanf("%s", p->name) != 1) return;

     printf("HitPoint: ");
     if (scanf("%d", &p->Hp) != 1) return;

	 printf("攻撃力:");
	 if (scanf("%d", &p->Attack) != 1) return;

	 printf("防御力:");
	 if (scanf("%d", &p->Diffence) != 1) return;

	 printf("素早さ:");
	 if (scanf("%d", &p->Speed) != 1) return;

     num_members++;
	 }
	 return;
}
 
void Save()
{    
     FILE *fp = fopen("save.dat", "wb");
     if (fp==NULL) 
	 {    
          printf("セーブできませんでした \n");

		  rewind(stdin);
		  getchar();

          return;
     }
     fwrite(members, sizeof(NINGEN), num_members, fp);
     fclose(fp);

     printf("セーブしました! \n");

	 rewind(stdin);
	 getchar();

	 return;
}
 
void Load()
{    
     int n;
     FILE *fp = fopen("save.dat", "rb");
     if (!fp) 
	 {    
          printf("データがありません! \n");

		  rewind(stdin);
		  getchar();

          return;
     }

     num_members = fread(members, sizeof(NINGEN), MAX_MEMBERS, fp);
     fclose(fp);

	 printf("ロードしました \n");

	 rewind(stdin);
	 getchar();
	 
     printf("今の仲間は%d人です \n", num_members);

	 rewind(stdin);
	 getchar();

	 return;
}
 
int main(void)
{      
     while (1) 
	 {    
          int n;
          while (1) 
		  {
			 printf("  1. ステータス表示 \n");
  			 printf("  2. 仲間を増やす! \n");  
                         printf("  3. データのセーブ \n");
                         printf("  4. データのロード \n" );
  			 printf("  5. 終了 \n");
	
                          if (scanf("%d", &n) == 1 && n >= 1 && n <= 5) 
			  break;

                           if (feof(stdin) ) 
			   return 0;

               while (getchar() !='\n');
          }
          if (n == 1) Display();
          else if (n == 2) Add();
          else if (n == 3) Save();
          else if (n == 4) Load();
          else break;
	 }
      return 0;
}
ありがとうございました。無事にできました。

かずま

Re: わからなくて困ってます

#10

投稿記事 by かずま » 9年前

SZ-TS さんが書きました: ありがとうございました。無事にできました。
できていません。テストはしましたか?

SZ-TS

Re: わからなくて困ってます

#11

投稿記事 by SZ-TS » 9年前

コード:

#include <stdio.h>

#define MAX_MEMBERS 5
 
typedef struct
{    
     char name[40];
     int Hp;
	 int Attack;
	 int Diffence;
	 int Speed;
} NINGEN;
 
NINGEN members[MAX_MEMBERS];
int num_members;
int count;

void Display()
{
        if (num_members == 0) 
	{    
         printf("データがありません! \n");

		 rewind(stdin);
		 getchar();

         return;
    }
	printf("====仲間のステータスを表示します==== \n");

	rewind(stdin);
	getchar();

    for (count = 0; count < num_members; count++) 
	{  
		 NINGEN *p = &members[count];

         printf(" [%d]\n    名前: %s \n    HitPoint: %d \n    攻撃力:%d \n    防御力:%d \n    素早さ:%d \n", count+1, p->name, p->Hp, p->Attack, p->Diffence, p->Speed);
    }
	rewind(stdin);
	getchar();

	return;
}
 
void Add()
{     
     NINGEN *p;
     if (num_members == MAX_MEMBERS) 
	 {    
          printf("これ以上仲間にできない! \n");

		  rewind(stdin);
		  getchar();

          return ;
	 }
	 
     p = &members[num_members];

	 printf("=====仲間のステータスを入力してください===== \n");

         printf("名前: ");
         if (scanf("%s", p->name) != 1) return;

         printf("HitPoint: ");
         if (scanf("%d", &p->Hp) != 1) return;

	 printf("攻撃力:");
	 if (scanf("%d", &p->Attack) != 1) return;

	 printf("防御力:");
	 if (scanf("%d", &p->Diffence) != 1) return;

	 printf("素早さ:");
	 if (scanf("%d", &p->Speed) != 1) return;

         num_members++;

	 return;
}
 
void Save()
{    
     FILE *fp = fopen("save.dat", "wb");
     if (fp==NULL) 
	 {    
               printf("セーブできませんでした \n");

	       rewind(stdin);
	       getchar();

               return;
         }
          fwrite(members, sizeof(NINGEN), num_members, fp);
          fclose(fp);

          printf("セーブしました! \n");

	  rewind(stdin);
	  getchar();

	  return;
}
 
void Load()
{    
     int n;
     FILE *fp = fopen("save.dat", "rb");
     if (!fp) 
	 {    
              printf("データがありません! \n");

	      rewind(stdin);
	      getchar();

              return;
         }

         num_members = fread(members, sizeof(NINGEN), MAX_MEMBERS, fp);
         fclose(fp);

	 printf("ロードしました \n");

	 rewind(stdin);
	 getchar();
	 
         printf("今の仲間は%d人です \n", num_members);

	 rewind(stdin);
	 getchar();

	 return;
}
 
int main(void)
{      
     while (1) 
	 {    
          int n;
          while (1) 
		  {
			   
			   printf("  1. ステータス表示 \n");  

			   printf("  2. 仲間を増やす! \n");  

			   printf("  3. データのセーブ \n");

         printf("  4. データのロード \n" );

			    printf("  5. 終了 \n");
			   
			    printf("数字を入力してください⇒");
                            if (scanf("%d", &n) == 1 && n >= 1 && n <= 5) 
			    break;

                            if (feof(stdin) ) 
			    return 0;

                            while (getchar() !='\n');
                    }
                    if (n == 1) Display();
                   else if (n == 2) Add();
                   else if (n == 3) Save();
                   else if (n == 4) Load();
                   else break;
	 }
         return 0;
}
ゲームの仕様で仲間の入力を1人ずつに戻すことにしました。
ご迷惑をおかけして申し訳ありませんでした。

SZ=TS

Re: わからなくて困ってます

#12

投稿記事 by SZ=TS » 9年前

ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る