ページ 11

[C]分割コンパイルを用いたファイルの読み込み

Posted: 2013年5月07日(火) 22:38
by teru
初めて質問させていただきます、teruという者です。
現在、C言語でゲーム製作をしています。コンパイラはVC++2008、ライブラリはDxlibraryを使用しています。
OSはWindows7 64bitです。

マップのデータをテキストファイルに書いておき、それを読み込むという処理をしようとしています。

コード:

/* main.cpp */
#include "DxLib.h"
#include "map.h"


int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
	ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen(DX_SCREEN_BACK);

	AllocConsole();
    freopen("CONOUT$", "w", stdout);

	/* 構造体宣言 */
	MAP map;

	/* メンバの初期化 */
	map_ini(&map);

	/* ファイル読み込み */
	map_data_read(&map);
	

	while(ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0)
	{
		map_draw(&map);
	}

	DxLib_End();
	return 0;

}

コード:

/*map.cpp*/
#include "DxLib.h"
#include "map.h"

void map_ini(MAP *map){
	memset(map,0,sizeof(MAP));
	map->map = LoadGraph("img/m01.bmp");
}


int map_data_read(MAP *map){

	map->FileHandle = FileRead_open("1.txt");
	if(map->FileHandle == NULL){
		MessageBox(NULL,"ファイルの読み込みに失敗しました","エラー",MB_OK);
		return 0;
	} else {
		MessageBox(NULL,"ファイルを正常に読み込みました","読み込み完了",MB_OK);
		return map->FileHandle;
	}

	FileRead_scanf(map->FileHandle,"%d,%d",map->ReadNumY,map->ReadNumX);
	printf("%d\n,%d,%d",map->FileHandle,map->ReadNumY,map->ReadNumX);

	for(int y=0;y<map->ReadNumY;y++){
		for(int x=0;x<map->ReadNumX;x++){
			FileRead_scanf(map->FileHandle,"%d,",map->data);
			map->mapdata[y][x] = map->data;
			printf("%d",map->mapdata[y][x]);
		}
	}

	FileRead_close(map->FileHandle);
}


void map_draw(MAP *map){
	DrawGraph(10,10,map->map,TRUE);
}

コード:

#ifndef DEF_MAP_H
#define DEF_MAP_H

typedef struct{
	int map;
	int FileHandle;
	int ReadNumY,ReadNumX;
	int data;
	int mapdata[20][20];
} MAP;


void map_ini(MAP *map);

int map_data_read(MAP *map);

void map_draw(MAP *map);

#endif
テキストファイル

コード:

5,5
1,1,1,1,1
1,1,1,1,1
1,1,1,1,1
1,1,1,1,1
1,1,1,1,1
しかし、map.cppのFileRead_openの部分でファイルの内容を正常に読み込めていないようです。
テキストファイルを用意せず意図的にエラーを起こそうとした場合、MessageBoxは表示されたものの、OKを押しても強制終了してくれず。
テキストファイルをしっかりと用意した場合では、同様にMessageBoxは表示されるのですが、代入されるべきものが何も入っていないようです(printfで表示したものになにもでない)。
どちらのパターンでもコンパイラはエラーを吐かず、正常に動作しているようなのです。

また、ファイル読み込みの処理自体は、分割コンパイルをせずに全てmain.cppに書いた場合、正常に動作してくれるのを確認しています。
それをそのまま分割コンパイル仕様にしたつもりなのですが…。
一見正常に動作しているように見えてしまっている分、何が問題なのかがわかりません。

もしかしたら基本的な部分の見落としがあるのやもと思い、質問させていただきました。
なにかヒントをいただければ幸いです。
よろしくお願いします。

補足です。
mapdata[20][20]は、今後いくつかのマップに対して使いまわすつもりなのでテキストファイルにあるものより大きく用意してます。
DrawGraphはとりあえず用意しているだけで、ファイル読み込みが正常動作した後に書き直すつもりです。

Re: [C]分割コンパイルを用いたファイルの読み込み

Posted: 2013年5月07日(火) 22:58
by nil
FileRead_scanfの引数はポインタです

Re: [C]分割コンパイルを用いたファイルの読み込み

Posted: 2013年5月07日(火) 22:59
by box
全体をザッとながめた感じでは、
teru さんが書きました:

コード:

/*map.cpp*/
int map_data_read(MAP *map){

	map->FileHandle = FileRead_open("1.txt");
	if(map->FileHandle == NULL){
		MessageBox(NULL,"ファイルの読み込みに失敗しました","エラー",MB_OK);
		return 0;
	} else {
		MessageBox(NULL,"ファイルを正常に読み込みました","読み込み完了",MB_OK);
		return map->FileHandle;
	}
ここのif文で、条件の真偽にかかわらず呼び出し元へreturnしています。よって、
teru さんが書きました:

コード:

	FileRead_scanf(map->FileHandle,"%d,%d",map->ReadNumY,map->ReadNumX);
	printf("%d\n,%d,%d",map->FileHandle,map->ReadNumY,map->ReadNumX);

	for(int y=0;y<map->ReadNumY;y++){
		for(int x=0;x<map->ReadNumX;x++){
			FileRead_scanf(map->FileHandle,"%d,",map->data);
			map->mapdata[y][x] = map->data;
			printf("%d",map->mapdata[y][x]);
		}
	}

	FileRead_close(map->FileHandle);
}
ここの部分を通っていないように見えます。

Re: [C]分割コンパイルを用いたファイルの読み込み

Posted: 2013年5月07日(火) 23:51
by softya(ソフト屋)
大半のバグは、コンパイルはエラーにならず異常終了もしません。
つまりロジック・バグなのです。このバグを取るためには色々と工夫してやらねばなりません。
既に問題点は指摘されていますが、この問題を自分で見つかるための技術となります。

参考に私の書いたものです。
「簡単RPG講座 番外編。 デバッグ入門 • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/blog.php?u=114&b=982&c=2

FileRead_scanfした内容などをprintfして確認することができます。

Re: [C]分割コンパイルを用いたファイルの読み込み

Posted: 2013年5月08日(水) 00:25
by teru
涼雅 さんが書きました:FileRead_scanfの引数はポインタです
ご指摘ありがとうございます。
map構造体のメンバ、FileHandleのポインタを「map->FileHandle」で渡せていると思い込んでました。
構造体とポインタに関することで、理解していない、または誤認している部分があるみたいです。
言っていただいたことがパッと理解できないので、勉強しなおして試行錯誤してみます。
box さんが書きました:ここのif文で、条件の真偽にかかわらず呼び出し元へreturnしています。
確かにそうですね。
main.cppに全て書いた時は「if(FileHandle) == NULL) return 0;」のみで問題なく動いてたため、その部分を見落としていました。
後はFileRead_scanfの引数の部分が解決すれば、全てうまくいくと思います。
ご指摘ありがとうございます。
softya(ソフト屋) さんが書きました:大半のバグは、コンパイルはエラーにならず異常終了もしません。
つまりロジック・バグなのです。このバグを取るためには色々と工夫してやらねばなりません。
既に問題点は指摘されていますが、この問題を自分で見つかるための技術となります。
ロジック・バグという見方をしたことはありませんでした。コンパイル結果のみに固執してしまっていたようです。
リンクをわざわざ張っていただいてありがとうございます。
色々なデバックのやり方も、今後勉強していこうと思います。


答えてくださった皆様、ありがとうございました。質問して本当によかったです。
今回教えていただいた内容を元に、勉強しつつまた色々試してみよう思います。
どうしても行き詰ってしまった時にまた、質問しに来ると思います。
その時はまた、どうかお願いします。