<fstream.hのすすめ>

最近ファイルを扱うプログラムを作る機会があったので、それに関する小ネタを書こうと思います。
注意 初心者なので、書いてある内容に間違いや勘違いがあるかもしれません。「自分も初心者だけど
、これからファイル操作とかやってみたいなぁ」くらいの人に読んでもらえると幸いです。

Cでファイルを扱う方法は、有名なところでFILE型があります。
FILE *fp;
fp = fopen(〜なんたら
ってやつですね。
しかし、今回のプログラムではC++を使っていたので、なんとなくC++特有なファイル制御を使ってみました



1、やってみよう

C++には標準入出力というのも(例えばcout、cinみたいなもの)があって、その派生クラスにfstreamがあります。
これは読んで字のごとく、ファイルを扱う事ができるクラスです。
今回はこれを使って、ゲームのデータをセーブするコードを考えてみます。
派生クラスなので、<<や>>も同様に使えるはずです。
#include<iostream.h>
#include<fstream.h>
int main(){
fstream fp;
fp.open("data",ios::out|ios::binary); //"data"という名前のファイルをバイナリ書き込み専用で開きます。
long l = 10000; //long型のlという変数を宣言し、10000を代入します。
fp << l; //lを書き出し。
fp.close();
return 0;
}
これでOKなはず。次は読み込みをしてみます。
同じ所は省略
fp.open("data",ios::in|ios::binary);//"data"という名前のファイルをバイナリ読み込み専用で開きます。
fp >> l;//lを読みこみ。
fp.close();
cout << "l = " << l;//画面に出力。

結果


読みこみも正常ですね。これで終了です。(早



2、しかし、ちょっとまて


ところで、出来たファイル"data"をメモ帳で見てみましょう。


なんじゃこりゃ
なんかセーブしたデータが丸見えです。いや、丸見えの方が都合の良いこともありますが、ほとんどの
ゲームでは見られたく無いことのほうが多いでしょう。
そもそも、long型という4バイトのデータを記録したのに、5バイトかけて保存されているのも気に食いません。
そして、もっと大きな問題は、2つのデータをセーブしたときに、
long m1 = 10,m2 = 20,m3;//m1、m2、m3を宣言し、m1に10、m2に20を代入。
fp << m1 << m2;//m1とm2を書き込む。
fp >> m3;//m3に読み込む。
cout << "m3 = " << m3;


と全く異なったデータになってしまうことです。



3、解決法


なんか良い方法がないかなと探していると、タイムリーにネット上に解決するコードがありました。
それは、templateを使ったもので、
template<class T>
fstream & operator << (fstream& out,T& val)
{
out.write((char*)&val,sizeof(val));
return out;
}

fstream & operator >> (fstream& in,T& val)
{
in.read((char*)&val,sizeof(val));
return in;
}
これだけです。実に簡単。
実際に書き出しをして、今度はバイナリエディタで見てみると、
long l = 10;
fp << l;


0A000000は、10進方で10の事です。
狙い通り、テキストエディタで見ても内容はパッと見わかりません。(もちろん読もうとすれば読まれますが)
しかも、このコードの特徴は複数のデータを簡単にセーブ出来ることで、例えば
RPGのキャラのデータが入った構造体を4人分(例として、chara1、chara2、chara3、chara4)
セーブするときは、
fp << chara1 << chara2 << chara3 << chara4;
これで済んでしまいます。読み込みも順番さえ覚えておけば良いだけです。
問題もありますが、かなり使えるコードだと思います。
これにて終了。

最後に、このコードを載せていた、どこかのHPの名も知らぬ管理人さんありがとう(ぉぃ


1年 J科 藁科