- ベストアンサー
C++におけるバイナリファイルの入出力について
- C++におけるバイナリファイルの入出力について説明します。VisualStudioExpress2015のC++でセーブデータの読み書きを行う際に、アクセス違反が発生する問題があります。質問者はセーブデータが存在しない場合はクラスの情報を書き込み、存在する場合は情報を読み込むプログラムを作成したいと考えています。
- 質問者は、セーブデータをバイナリファイルに保存する方法を学びたいと考えています。質問者のプログラムでは、クラスをバイナリ形式でファイルに書き込む(write)関数と、ファイルからクラスを読み込む(read)関数が実装されています。しかし、問題のコードではセーブデータの読み書き時にアクセス違反が発生してしまいます。
- 質問者は、バイナリファイルの入出力を使用してセーブデータの読み書きを行いたいと考えています。しかし、現在の方法がうまく機能しない場合、他の方法を教えて欲しいと述べています。質問者は、ゲームのセーブデータのような大量のデータをクラスごとにバイナリファイルに保存したいと考えています。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
クラス(インスタンス)をそのままfwrite/freadして使うのは色々難しいと思います。 上記プログラムでいえば、read時にstr用のメモリを割り当てていなかったり、write時もmMap内部のデータを出力できていないのではと思います。 そのような目的でboost::serializationというライブラリもありますのが、これもC/C++に慣れていないと難しいかなと思います。 クラス内の変数1つずつをread/writeする処理を記述する方が簡単かと思います。
その他の回答 (2)
- koi1234
- ベストアンサー率53% (1866/3459)
ちゃんと確認はしていません ・メインでオープンしたままクローズしていない ・各関数(Read/Write)内でもオープンしてるから 排他制御でエラーになってるとか言った話と違いますか?
お礼
回答ありがとうございます。 確かにおっしゃる通り、ストリームの閉じ忘れではないかと思い試したところ、同じところでエラーが出てしまいました。 やはり、地道にひとつずつ変数を読み書きするしかなさそうです…
- m-take0220
- ベストアンサー率60% (477/782)
stringは可変長の文字列を扱いますから、内部に文字列データを保持していません。必要なメモリを確保して、そのポインタを保持するようになっています。 なので、sizeof(string)はデータの大きさを表していないし、fwriteでファイルに書き込んでも、正しく読み込みはできません。 char *pstr = new char[10]; strcpy(pstr, "test"); fwrite(&pstr, sizeof(pstr), 1, fp); としても、 fread(&pstr, sizeof(pstr), 1, fp); で読み出せるのは、書き込んだ時のpstrが指していたポインタの値であって、その時点でそのメモリが確保されている保証もなければ、内容が"test"である保証もないわけですよ。 mapも然りで、sizeofでmapが保持しているデータのサイズを取得することはできません。 あと、 > if (fopen_s(&fp, "セーブデータ.dat", "rb") != 0) { > write(); > } 「ファイルがオープンできない=ファイルが存在しない」と判断しているんでしょうが、オープンできない状況は他にも、アクセス権がない、別のプログラムが排他モードでオーブンしている、などが普通にあります。特殊な状況なら、もっといろいろな原因が出てきます。存在するかどうかで処理を変えたいなら、そのような記述にしましょう。
お礼
回答ありがとうございます。 ポインタをファイルに書き込んでも読み込むときにはそのポインタは使えないのですね… ファイルが存在するかどうかはFindFirstFileのような関数を使った方がよいということでしょうか。肝に銘じておきます。
お礼
回答ありがとうございます。 やはり、fwrite/freadではまとめて書き込むには限界があるのですね… ライブラリの方、拝見しましたが確かに自分には少し敷居が高いと感じたので、繰り返しなどを用いて一つ一つ値を書き込んでいこうかと思います。ライブラリの方は次の機会のために参考にさせていただきます。