読者です 読者をやめる 読者になる 読者になる

C++でのバイナリファイルの入出力について

C++ではファイル入出力にfstream型(入力:istream,出力:ostream)を使います。
404 Not Found
上のページの「◆ブロック単位のファイル入出力」(つまりバイナリファイルの入出力)では

istream& read(char* buf, streamsize size);
ostream& write(char* buf, streamsize size);

と書いてあり、この関数を使えばうまくバイナリファイルを読み書きできる気がします。


しかし、対象のバイナリファイルがchar型であればリンク先のサンプルも使えるのですが、
double型やfloat型だった場合、どうやって読み書きしたらいいかちょっとサンプルからはわかりません。
(昨日はこれで小一時間悩んだ)


実はC++編(標準ライブラリ) 第33章 ファイルストリームにもあるように、ifstreamとofstreamは

typedef basic_ifstream<char> ifstream;
typedef basic_ofstream<char> ofstream;

とtypedef宣言されているので、基本的にバイナリファイルはchar型で読み書きする仕様らしいです。


では、double型の配列がバイナリフォーマットで記録されている場合、どうやって読み出すかというと、
1つの方法として、バイナリファイルはchar配列だと思ってsize分だけ読み込んであげることで読み込めます。

#include <iostream>
#include <string>
#include <fstream>

int main(){
    //ファイル名
    std::string filename = "image.raw";  
    //ファイル読み込み
    std::ifstream iFstrm( filename.c_str(), std::ios::binary );

    //ios::binaryはWindows環境で付け忘れると
    //バイナリファイルだと認識してくれないので注意

    if (iFstrm.fail()){
        std::cerr << "Error : Could not open" << std::endl;
        //なんか終了処理を入れる
    }
    //読み込むファイル格納用配列
    double input_image[256][256];
    
    //(char*)でキャストする
    //読み込む分だけサイズ指定する[多分sizeof(input_image)でもいいと思う]
    iFstrm.read((char*)input_image,sizeof(double)*256*256);

    //ここらへんで何か処理をする!

    //読み込み終了
    iFstrm.close();
    
    return 0;
}
  • この方法だとchar型以外でバイナリファイルがフォーマットされていても(char*)でキャストしなければならず気持ち悪い
  • もっとテンプレートを駆使してifstream・ofstreamの派生型を作った方がC++らしくなると思う
  • でもこの方法が一番簡単なんだよね(´・ω・`)