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

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

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

#1

投稿記事 by teru » 7年前

初めて質問させていただきます、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はとりあえず用意しているだけで、ファイル読み込みが正常動作した後に書き直すつもりです。

nil
記事: 428
登録日時: 8年前

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

#2

投稿記事 by nil » 7年前

FileRead_scanfの引数はポインタです

box
記事: 1746
登録日時: 9年前

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

#3

投稿記事 by box » 7年前

全体をザッとながめた感じでは、
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);
}
ここの部分を通っていないように見えます。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

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

#4

投稿記事 by softya(ソフト屋) » 7年前

大半のバグは、コンパイルはエラーにならず異常終了もしません。
つまりロジック・バグなのです。このバグを取るためには色々と工夫してやらねばなりません。
既に問題点は指摘されていますが、この問題を自分で見つかるための技術となります。

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

FileRead_scanfした内容などをprintfして確認することができます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

teru

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

#5

投稿記事 by teru » 7年前

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


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

閉鎖

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