char型二次元配列マップとファイル読み込み

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

char型二次元配列マップとファイル読み込み

#1

投稿記事 by aridai » 5年前

DxLibでゲームを作っている者ですが、
アクションゲームのマップにchar型の二次元配列を使っています。
そこで、テキストファイルからマップデータを読み込む仕組みを考えてみたのですが、
よくわかりませんでした。
画面サイズは640x480で、1つのマップチップのサイズは32x32です。
ステージ全体のサイズは 6400x480で、

コード:

char stagedata[ 15 ][ 200 ];
この配列に "res\\mapdata\\map1.txt" の中身を代入したいのです。
ファイル名は

コード:

char buf[256];
sprintf(buf, "res\\mapdata\\map%d.txt", program.stagenum);
// program.stagenumは現在のステージを表す構造体変数です。
// 別のところで定義、宣言されています。
このようにして、取得出来ました。
しかし、二次元配列にテキストファイルの行を代入していくやり方がわかりません。
char型の配列は文字列を扱うものだと思うのですが、
改行を表す文字コードをどうすればいいかわかりません。
どなたか、ご回答お願いします。

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

Re: char型二次元配列マップとファイル読み込み

#2

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

"res\\mapdata\\map1.txt" の中身がわかりませんが、DXライブラリを使用しているのなら素直にFileRead_getsで読みこめばいいのではないでしょうか?
改行を表す文字コードはFileRead_getsが勝手に処理して消してくれます。

コード:

#include <DxLib.h>

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int) {
	ChangeWindowMode(TRUE);
	SetGraphMode(800, 600, 32);
	DxLib_Init();

	struct {
		int stagenum;
	} program;
	program.stagenum = 1;
	char buf[256];
	sprintf(buf, "res\\mapdata\\map%d.txt", program.stagenum);
	int handle = FileRead_open(buf, FALSE);
	if (handle == 0) {
		printfDx("file read error\n");
	} else {
		char stagedata[ 15 ][ 200 ];
		for (int i = 0; i < 15; i++) {
			FileRead_gets(stagedata[i], sizeof(stagedata[i]), handle);
		}
		FileRead_close(handle);

		for (int i = 0; i < 15; i++) {
			printfDx("%d %s\n", lstrlenA(stagedata[i]), stagedata[i]);
		}
	}

	WaitKey();

	DxLib_End();
	return 0;
}
テストに使用したres\mapdata\map1.txt

コード:

!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&
"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&'
#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&'(
$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&'()
%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&'()*
&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&'()*+
'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&'()*+,
()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&'()*+,-
)*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&'()*+,-.
*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&'()*+,-./
+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&'()*+,-./0
,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&'()*+,-./01
-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&'()*+,-./012
./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&'()*+,-./0123
/0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&'()*+,-./01234
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

aridai
記事: 34
登録日時: 5年前

Re: char型二次元配列マップとファイル読み込み

#3

投稿記事 by aridai » 5年前

返信ありがとうございます。
ですが、なぜか横に16文字しか表示されませんした。
テキストファイルの文字コードを色々いじってみたのですが、できませんでした。

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

Re: char型二次元配列マップとファイル読み込み

#4

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

aridai さんが書きました:なぜか横に16文字しか表示されませんした。
テキストファイルの文字コードを色々いじってみたのですが、できませんでした。
テストに使用したソースコードと入力のテキストファイルを提示(アップロード)することはできますか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

aridai
記事: 34
登録日時: 5年前

Re: char型二次元配列マップとファイル読み込み

#5

投稿記事 by aridai » 5年前

https://www.dropbox.com/s/nkou2iehwd5ya ... e.zip?dl=0
DropBoxです。
あと、私はこの読み込みのシステムをワールドマップにも使いたかったので、
小さいサイズで試していました。
ワールドマップの規模 : 640x480 (char worldmapdata[15][20])
ステージデータの規模 : 6400x480 (char stagedata[15][200])
このようになっています。

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

Re: char型二次元配列マップとファイル読み込み

#6

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

aridai さんが書きました:worldmap.cpp 35行目~

コード:

void drawmap()
{
	for (int y = 0; y <= 20; y++)
	{
		for (int x = 0; x <= 15; x++)
		{
			if (worldmapdata[y][x] == '0')
			{
				DrawBox(x * 32, y * 32, x * 32 + 32, y * 32 + 32, GetColor(255, 255, 255), FALSE);
			}
		}
	}
}
横に16文字しか表示しない実装なので、横に16文字しか表示されないのは当たり前ではないでしょうか?
worldmapdata[16]以降へのアクセスは未定義の動作になりますが、それを利用して横の表示文字数をコードの直感的な解釈より増やそうと考えてはいけません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

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

Re: char型二次元配列マップとファイル読み込み

#7

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

また、終端文字を入れないといけないため、200要素しか確保されていない配列に200文字のマップデータをFileRead_gets()で直接入れることはできません。
マップデータの配列をギリギリの要素数にしたければ、

コード:

for (int i = 0; i < 15; i++) {
	char map_buffer[256] = {0};
	FileRead_gets(map_buffer, sizeof(map_buffer), handle);
	for (int j = 0; j < 200; j++) worlddmapdata[i][j] = map_buffer[j];
}
のようにするといいでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

aridai
記事: 34
登録日時: 5年前

Re: char型二次元配列マップとファイル読み込み

#8

投稿記事 by aridai » 5年前

ありがとうございました。
無事解決しました。
みけCATさん、ありがとうございました。

aridai
記事: 34
登録日時: 5年前

Re: char型二次元配列マップとファイル読み込み

#9

投稿記事 by aridai » 5年前

本当に助かりました。
ありがとうございました。

閉鎖

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