トップページ > 記事閲覧
fread()で二次元配列を読み込めません
名前:田中一郎 日時: 2019/12/06 23:50

DXライブラリでゲーム製作をしている初心者です。 ドラクエのようなRPGゲームを作っていて、ワールドマップを作っている段階です。 一度単純な数値マップを作成し、それから高度な数値マップを作成するというやり方を取っています。 例)旧数値マップ→新数値マップ→ワールドマップ描画 今までは1つのファイルに新数値マップをグローバル変数として設定し、それを元に描画するというやり方を取っていました。 ですが、これだとマップの書き直しをする度に、新数値マップを旧数値マップから作り直してファイルに貼り付けたりと手間がかかっていました。 なので、旧数値マップも新数値マップもtxtファイルにして、1回の実行で全部済ませられるように変更しようと思いました。 そして今その作業をしている最中なのですが、旧数値マップ.txt から数値を読み込んで、二次元配列sword_map[][]に代入しようとしているのですが、 fread()を使う所(あ)でエラーが起こってしまいます。 画面に「ファイルFP_SWORDを開く事ができません」と出て終了してしまいます。 全体のコードが3000行位あるので、問題のある一部だけ抜粋しています。 なぜfread()がエラーになってしまうんでしょうか。 どなたか分かる方がいましたら教えて下さると助かります。 #define SWORDFIELD_WIDTH 33 #define SWORDFIELD_HEIGHT 29 sword_map[SWORDFIELD_HEIGHT][SWORDFIELD_WIDTH]; newsword_map[SWORDFIELD_HEIGHT][SWORDFIELD_WIDTH]; void newmapform_sword() { FILE *FP; if ((FP = fopen("旧sword_map.txt", "rb")) == NULL) { printfDx("旧sword_map.txtの読み込みに失敗しました"); WaitKey(); DxLib_End(); } if (fread(sword_map, sizeof sword_map, 1, FP) != 1) {・・・・・・・・・・・・(あ) printfDx("ファイルFP_SWORDを開く事ができません"); WaitKey(); exit(1); }     /*ここにsword_map[][]に入っている数値に対応した新数値をnewsword_map[][]に代入している(コードは省略)*/     //ここでnewsword_map[][]の配列の数値を「新sword_map.txt」に張り付ける FILE *FP2; if ((FP2 = fopen("新sword_map.txt", "wb")) == NULL) { printfDx("新sword_map.txtの書き込みに失敗しました"); WaitKey(); DxLib_End(); } if (fwrite(newsword_map, sizeof newsword_map, 1, FP2) == NULL) { printfDx("FP2書き込みエラー"); exit(1); } }
メンテ

Page: 1 |

Re: fread()で二次元配列を読み込めません ( No.1 )
名前:管理人 日時:2019/12/07 01:24

fread は主にバイナリファイルを読み込む為のものですので、仮にテキストファイルの内容が 11211 22344 13111 のようになっていて、fread で読み込んでも、得られる値は 1,1,2,1,1, 2,2,3,4,4, 1,3,1,1,1 ではなく 49,49,50,49,49,13,10, 50,50,51,52,52,13,10, 49,51,49,49,49 です( 49は文字『1』を表す値、50は文字『2』を表す値、51は文字『3』を表す値、52は文字『4』を表す値、 13と10は改行を表す値、詳しくは『アスキーコード表』でネット検索してみてください ) 同様に fwrite でファイルに書き出す場合も char Map[3][5] = { { 1,1,2,1,1 }, { 2,2,3,4,4 }, { 1,3,1,1,1 }, }; FP = fopen( "map.txt", "wb" ); fwrite( Map, sizeof( Map ), 1, FP ); fclose( FP ); としても、作成される map.txt には何も文字は記録されません( 数値1,2,3,4はそれぞれ文字は割り当てられていないため ) とりあえず 旧sword_map.txt の内容がどのような記述のされ方をしているのか分からないと ご助言できませんので、旧sword_map.txt の内容を貼り付けていただけないでしょうか?
メンテ
Re: fread()で二次元配列を読み込めません ( No.2 )
名前:田中一郎 日時:2019/12/07 13:34

回答ありがとうございます。 以下に旧sword_map.txtの内容を貼り付けます。 \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ V \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ V V V \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ V V V V V V V \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ V V    V V V \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ V V      V V  \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ V           \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ V             \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ V              \ \ \ \ \ \ \ \ \ \ \   \ \ \ \ \ \ V              \ \ \ \ \ \ \ \ \ \    \ \ \ \ \ \ V              \ \ \ \ \ \ \ \ \     \ \ \ \ \ \ V              \ \ \ \ \ \ \ \ \    \ \ \ \ \ \ \ V    W             \ \  \ \     \ \ \ \ \ \ \ V                          \ \ \ \ \ \ \ V                           \ \ \ \ \ \ V                           \ \ \ \ \ \ V    W                \       \ \ \ \ \ \ V               \ \   \ \ \     \ \ \ \ \ \ \ V               \ \ \ \ \ \ \ \ \   \ \ \ \ \ \ \ V V              \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ V V             \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ V V V            \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ V V V      V    \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ V V      V V   \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ V V V V V V V V V \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ V V V V V V V V \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ V V V V \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ □の部分はtxtでは黒点で表示されています。
メンテ
Re: fread()で二次元配列を読み込めません ( No.3 )
名前:管理人 日時:2019/12/07 17:34

> □の部分はtxtでは黒点で表示されています。 すみません、掲示板の書き込み処理を通した際にデータが変化してしまっているようです 大変お手数で申し訳ありませんがこちらのギガファイル便のようなファイルアップローダーに 旧sword_map.txt をアップしていただけないでしょうか? m(_ _;m <ギガファイル便> https://gigafile.nu/
メンテ
Re: fread()で二次元配列を読み込めません ( No.4 )
名前:田中一郎 日時:2019/12/07 17:47

以下にファイルをアップしておきます。 パスワードを求められたら0000で設定しています。 //18.gigafile.nu/1214-dcbded61dbe5712725d9d6f1905e2e055
メンテ
Re: fread()で二次元配列を読み込めません ( No.5 )
名前:管理人 日時:2019/12/08 22:51

ファイルのアップありがとうございます ファイルの中身を拝見させていただきましたところ一つ疑問が… 旧sword_map.txt はどのように作成されたのでしょうか? ( テキストエディタで入力した場合では存在しないはずの数値が 0 の文字がありましたので、 旧sword_map.txt は手入力で作成されたテキストファイルではないでしょうか? )
メンテ
Re: fread()で二次元配列を読み込めません ( No.6 )
名前:yumetodo 日時:2019/12/08 23:37

いや、きちんと4byteずつなので本当にint32_tかなにかの配列を書き出したんじゃないですかね。
メンテ
Re: fread()で二次元配列を読み込めません ( No.7 )
名前:B.E 日時:2019/12/09 02:12

横から失礼します。 テキストファイルじゃなくて多分バイナリファイルじゃないですかね? サイズも3,828 バイトなので、 #define SWORDFIELD_WIDTH 33 #define SWORDFIELD_HEIGHT 29 int sword_map[SWORDFIELD_HEIGHT][SWORDFIELD_WIDTH]; で確保したサイズと同じなんで間違いないと思いますよ。 (拡張子は.txtから別のものにかえた方がいいですよ。) それに自分の環境では↓でエラーにならず読み込めますが? FILE *FP; if ((FP = fopen("旧sword_map.txt", "rb")) == NULL) { printfDx("旧sword_map.txtの読み込みに失敗しました"); WaitKey(); DxLib_End(); } if (fread(sword_map, sizeof sword_map, 1, FP) != 1) { printfDx("ファイルFP_SWORDを開く事ができません"); WaitKey(); exit(1); } ↓読み込んだデータの数値を描画した画像 ttps://thuploader.orz.hm/img/?mode=dl&id=1783 ※パスワードは同じく「0000」です。 おそらく、他の箇所でエラーになってるのではないでしょうか? コードで気になる個所としてはfclose();が抜けている所と、 ファイルサイズを調べずに固定サイズで読み込んでいるくらいですし…。 (ファイルサイズに関しては合致しているようなので、それでエラーにはなりませんしね…) あとDXライブラリにはFileRead_open()系の関数があって こっち使うとデータをDXアーカイブ形式に変換しても読み込めるので便利ですよ。 FileRead_size()とかで簡単にファイルサイズを調べられたりしますし…。
メンテ
Re: fread()で二次元配列を読み込めません ( No.8 )
名前:yumetodo 日時:2019/12/09 15:28

まあ余談ですがC++17でC++標準に追加されているfilesystem ライブラリでもファイルサイズはとってこれます。 ttps://cpprefjp.github.io/reference/filesystem/file_size.html
メンテ
Re: fread()で二次元配列を読み込めません ( No.9 )
名前:田中一郎 日時:2019/12/09 15:49

皆さん、回答ありがとうございます。 >テキストファイルじゃなくて多分バイナリファイルじゃないですかね? >サイズも3,828 バイトなので はい、B・Eさんの言ってる通り、旧sword_map.txtファイルにはバイナリデータで入力されています。 sword_map[][]にint型の整数値を入れて、旧sword_map.txtにバイナリデータで出力するという形にしていました。 >それに自分の環境では↓でエラーにならず読み込めますが? fread()がDXライブラリでは使えないのかと思っていたので、それを聞いて安心しました。 もう一度プログラムを見てみた所、1pxからRGB値を取り出すGetPixelSoftImage()の引数でx座標とy座標の値を反対に記述していました。 恐らくこれが原因でfread()がエラーを出力していたのだと思います。 >(拡張子は.txtから別のものにかえた方がいいですよ。) これは全く意識していませんでした。 txtファイルでも文字化けは起こってしまいますが、問題無く使えていたので... もし差支えなければどのような拡張子がお勧めなのか教えて頂けないでしょうか。 >あとDXライブラリにはFileRead_open()系の関数があって >こっち使うとデータをDXアーカイブ形式に変換しても読み込めるので便利ですよ。 >FileRead_size()とかで簡単にファイルサイズを調べられたりしますし…。 これはどこかで調べた事があったのですが、ザっと説明読んでfread()とは別物だと思っていたら、getcやgetsみたいに使う事が出来たんですね。 今度から試してみようと思います。 そしてこのプログラムなんですが、数値マップをtxtファイルに移して作業するよりも、プログラムの中で旧配列のまま新配列に変換することも出来ると思ったので、 txtファイルは使わずに行いました。 余計な手間をかけさせてしまってすみません。 でも皆さんのアドバイスはとても参考になりました。 これからのゲーム作りに活かしていきたいと思います。
メンテ
Re: fread()で二次元配列を読み込めません ( No.10 )
名前:B.E 日時:2019/12/09 23:32

>>txtファイルでも文字化けは起こってしまいますが、問題無く使えていたので... >>もし差支えなければどのような拡張子がお勧めなのか教えて頂けないでしょうか。 別にプログラム的には自分でファイルの中身分かっているのなら問題はないですけど、 Windows的には拡張子でファイル判断してるんで、あんまり中身と違う拡張子付けるのはよろしくないかと…。 あと他の人がコード見た時にテキストファイルを二次配列に読み込んでるように見えるので誤解の元になります。 拡張子の種類については、既存の拡張子と被ってなければなんでもいいですよ。 (別に拡張子自体付けなくても大丈夫です。) 既存の拡張子付けちゃうと、ダブルクリックとかで関連付けされたソフトで開こうとされちゃうので…。 まあ、基本的にファイルヘッダーを調べてソフト側で違うって判断するようになっているものが多いので、 さほど問題になる事はないですが…。 ちなみにテキストファイルはヘッダーが無い形式なので拡張子が.txtなら大抵のテキストエディタは中身が何であろうが開いちゃいます。 (あまり大きすぎるファイルだとエラーになったりしますが…)
メンテ
Re: fread()で二次元配列を読み込めません ( No.11 )
名前:田中一郎(解決) 日時:2019/12/10 22:20

>まあ余談ですがC++17でC++標準に追加されているfilesystem ライブラリでもファイルサイズはとってこれます。 >ttps://cpprefjp.github.io/reference/filesystem/file_size.html 前回の回答時に気づかずすみません(^^; C言語までしかやってないのでちょっと分からない所もありますが参考にしてみます。 >別にプログラム的には自分でファイルの中身分かっているのなら問題はないですけど、 >Windows的には拡張子でファイル判断してるんで、あんまり中身と違う拡張子付けるのはよろしくないかと…。 > >あと他の人がコード見た時にテキストファイルを二次配列に読み込んでるように見えるので誤解の元になります。 確かにtxtと書かれているのにバイナリファイルが入っていたらとまどいますよね。 素人なのであまり意識していませんでした。 >拡張子の種類については、既存の拡張子と被ってなければなんでもいいですよ。 >(別に拡張子自体付けなくても大丈夫です。) > >既存の拡張子付けちゃうと、ダブルクリックとかで関連付けされたソフトで開こうとされちゃうので…。 >まあ、基本的にファイルヘッダーを調べてソフト側で違うって判断するようになっているものが多いので、 >さほど問題になる事はないですが…。 なるほどです。ファイルだったら、どんなエディタでも大抵開けますからね。 >ちなみにテキストファイルはヘッダーが無い形式なので拡張子が.txtなら大抵のテキストエディタは中身が何であろうが開いちゃいます。 >(あまり大きすぎるファイルだとエラーになったりしますが…) そういう裏技もあるんですね、覚えておきます。 詳しく解説して下さってありがとうございます。 B・Eさん、yumetodoさん、管理人さん 回答して頂きありがとうございました。
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存