テキストファイルから構造体の配列に代入

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ほりでい
記事: 15
登録日時: 4年前

テキストファイルから構造体の配列に代入

#1

投稿記事 by ほりでい » 4年前

コード:

 
 //"humen/君の名は.txt"
10000000 10000000 10000000 20000000 10000000 10000000 10000000 20000000 
10000000 10000000 10000000 20000000 10000000 10000000 10000000 20000000 
10000000 20000000 10000000 20000000 10000000 20000000 10000000 20000000 
10000000 20000000 10000000 20000000 10000000 20000000 10000000 20000000 
10000000 10000000 10002000 10000000 10000000 10000000 10002000 10000000 
10000000 10000000 10002000 10000000 10000000 10000000 10002000 10000000 
10000000 10000000 10002000 10000000 10000000 10000000 10002000 10000000 
10000000 10000000 10002000 10000000 10000000 10000000 10002000 10000000 
10001000 10000000 10002000 10000000 10001000 10000000 10002000 10000000 
10001000 10000000 10002000 10000000 10001000 10000000 10002000 10000000 
10001000 10000000 10002000 10000000 10001000 10000000 10002000 10000000 
10001000 10000000 20002000 20000000 10001000 20002000 10002000 10000000 
10000000 10000000 10000000 10000000 10000000 10000000 10000000 10000000 
10001000 10001000 10200020 20002000 10001000 10001000 10200020 20002000 
20000000 20000000 20000000 20000000 20000000 20000000 20000000 20000000 
20002000 20002000 20100010 10001000 20002000 20002000 20100010 10001005 

コード:

 
#include <stdio.h>
#include "DxLib.h"

 int load_humen() {
 
 	typedef struct {
		char flag;
		int cnt;
		int knd;
		int place;
		bool lock = false;
	}humen_t;
	
	char humen_small[HUMEN_MAX];
	char yomikomu_mojiretu[HUMEN_MAX];
	
	AllocConsole();
	FILE* out = 0;
	int k = 0;
	freopen_s(&out, "CON", "w", stdout);
	
	
	int i = 0;

	char HANDL[] = "FILE開けません"; // 読み込み失敗";
	char fname[] = "humen/君の名は.txt";

	FILE* fp;
	fp = fopen("humen/君の名は.txt", "r");

	if (fp == NULL) {
		DrawFormatString(0, 0, GetColor(255, 255, 255), "%s", HANDL);
		return 1;
	}
	else {
		DrawFormatString(0, 0, GetColor(255, 255, 255), "%s", "開けたよ");
	}	
	
	while ((chr = fgetc(fp)) != EOF) {
		yomikomu_mojiretu[i] = chr;
		if (yomikomu_mojiretu[i] == 1) {
			humen[i].flag = 1;
		}
		else if (yomikomu_mojiretu[i] == 2) {
			humen[i].flag = 2;
		}
		else if (yomikomu_mojiretu[i] == 5) {
			humen[i].flag = 5;
		}
		else {
			humen[i].flag = 0;
		}
		printf("%s", &humen[i].flag);
		i++;
	}

	fclose(fp);
	
	while (humen[k].flag != NULL) {

		printf("%s", &humen[k].flag);
		k++;

	}
	
	WaitKey();
	
	
	fclose(out);
	FreeConsole();
	
	/*
	humen[0].flag = 1;
	for (int i = 1; i < HUMEN_MAX; i++) {
		if (humen[i - 1].flag == 1)humen[i].flag = 0;
		if (humen[i - 1].flag == 0)humen[i].flag = 0;
		if (humen[i - 10].flag == 0)humen[i].flag = 2;
		if (humen[i - 1].flag == 2)humen[i].flag = 0;
		if (humen[i - 20].flag == 2)humen[i].flag = 1;
		if (i == HUMEN_MAX - 1)humen[i].flag= 5;
	}
	*/
	
	return 0;
}

コード:

 
 //結果
020 20002000
20000000 20000000 20000000 20000000 20000000 20000000 20000000 20000000
20002000 20002000 20100010 10001000 20002000 20002000 20100010 10001005
00 20000000 20000000 20000000 20000000 20000000 20000000 20000000
20002000 20002000 20100010 10001000 20002000 20002000 20100010 10001005
 20000000 20000000 20000000 20000000 20000000
20002000 20002000 20100010 10001000 20002000 20002000 20100010 10001005
0000000 20000000 20000000
20002000 20002000 20100010 10001000 20002000 20002000 20100010 10001005
00000
20002000 20002000 20100010 10001000 20002000 20002000 20100010 10001005
2000 20100010 10001000 20002000 20002000 20100010 10001005
00 20002000 20002000 20100010 10001005
 20100010 10001005

コードが汚く、長くなってしまってすみません。
上からリズムアイコンが降りてくるような、音ゲーを作っているのですが、テキストファイルから構造体の配列に、読み取ることで苦戦しています。
テキストファイルの読み込み方は、C言語何でも掲示板で教えてもらったのですが、配列への代入がうまくいきません。
上のソースコードは全体の一部のなかのファイルをロードする関数です。
本当なら他のソースファイル、ヘッダーファイルなどからインクルードしてあるのですが、ソースコードがながくなってしまうので、上のソースコードで、必要な定義だけ書いておきました。もし何か足りなかたら言ってください。
上のソースコードを実行すると、上のような結果が出てしまい、テキストファイルないの数字と違ってしまい、
上からリズムアイコンが降ってこなくなってしまいます。
/**/内のソースこーどで試してみると、リズムアイコンが上から降ってきます。
試行錯誤を繰り返しましたが、上のソースコードが一番実行結果としてはまともになりました。
どなたかわかる方がいれば教えてください。<(_ _)>おねおね
説明が下手ですみません。<(_ _)>
何か不足な点がありましたら行ってください。お願いします。

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

Re: テキストファイルから構造体の配列に代入

#2

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

ほりでい さんが書きました:
4年前
もし何か足りなかたら言ってください。
変数?chrおよびhumen、定数?HUMEN_MAXの定義が書かれていないようです。

また、humenがhumen_t*型であると仮定すると、

コード:

		printf("%s", &humen[i].flag);

コード:

		printf("%s", &humen[k].flag);
は、範囲外へのアクセスで未定義動作になりますね。

コード:

		printf("%c", humen[i].flag);

コード:

		printf("%c", humen[k].flag);
のようにしたほうがいいでしょう。
オフトピック
上の引用部分、「足りなか」と「たら」の間に「っ」が足りないようですね。
また、
ほりでい さんが書きました:
4年前
何か不足な点がありましたら行ってください。
の「行ってください」は「言ってください」という意味でしょうか?
誤字に見える場所は、他にもあります。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

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

Re: テキストファイルから構造体の配列に代入

#3

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

DxLib.hとして以下のコードを用意し、humen/君の名は.txtとして添付のテキストファイルを置いて実行したところ、
0バイトの出力が得られました。
► スポイラーを表示
前提として「テキストファイルから」と書かれているため、
質問文中の「"humen/君の名は.txt"」に書かれている0、1、2、5という文字は、
バイトの値ではなく、それぞれ文字0、1、2、5 (ASCIIコード0x30、0x31、0x32、0x35)と解釈しました。
このとき、yomikomu_moziretu[​i]に入る数値は0でも1でも2でも5でもないため、
humen[​i].flagには0が代入され、
printf("%s", &humen[​i].flag);は未定義動作は起こさず0文字の文字列を出力します。
次に、humen[k].flag != NULLはk=0、human[k].flag=0なので偽となり、ループの中身は実行されません。
したがって、このコードでは0バイトの出力が得られます。

「上のソースコードを実行すると、上のような結果が出てしまい」と書かれていますが、
この「結果」が何を表しているかわかりません。
できれば、DXライブラリを使用せずに「テキストファイルから構造体の配列に代入」のテストのみを行う、
そのままコンパイルして実行可能なソースコードを提示していただけるとありがたいです。
添付ファイル
君の名は.txt
テスト用データ
(1.16 KiB) ダウンロード数: 124 回
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

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

Re: テキストファイルから構造体の配列に代入

#4

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

ほりでい さんが書きました:
4年前

コード:

	humen[0].flag = 1;
	for (int i = 1; i < HUMEN_MAX; i++) {
		if (humen[i - 1].flag == 1)humen[i].flag = 0;
		if (humen[i - 1].flag == 0)humen[i].flag = 0;
		if (humen[i - 10].flag == 0)humen[i].flag = 2;
		if (humen[i - 1].flag == 2)humen[i].flag = 0;
		if (humen[i - 20].flag == 2)humen[i].flag = 1;
		if (i == HUMEN_MAX - 1)humen[i].flag= 5;
	}
humenの定義が例えば

コード:

struct hoge { int flag; };
hoge buffer[100000];
hoge* humen = buffer + 100;
のようになっていれば問題ない可能性があります(HUMEN_MAXの値による)が、

コード:

struct hoge { int flag; };
hoge humen[100000];
のようになっている場合、humen[​i - 10]やhumen[​i - 20]で範囲外へのアクセスが発生し、危険です。

コード:

		if (i >= 10 && humen[i - 10].flag == 0)humen[i].flag = 2;
		if (i >= 20 && humen[i - 20].flag == 2)humen[i].flag = 1;
のようにした方がいいかもしれません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

ほりでい
記事: 15
登録日時: 4年前

Re: テキストファイルから構造体の配列に代入

#5

投稿記事 by ほりでい » 4年前

丁寧な説明ありがとうございました。

コード:

	while ((chr = fgetc(fp)) != EOF) {
		humen[i].flag  = chr;
		printf("%c", humen[i].flag);
		i++;
	}
上のコードでうまくいきました。
教えてもらったことを基に、色々変えたところ、なんとかリズムアイコンが下りてくるようになりました。
ありがとうございました。(人''▽`)

返信

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