2012-01-10 14 views
0

バイナリ入出力をテストするのに合理的に簡単なプログラムを試しています。私は基本的にヘッダー(文字列)といくつかのデータ(倍精度)でファイルを書いています。コードは以下の通りである。C++でのバイナリ入出力

#include <iostream> 
#include <iomanip> 
#include <fstream> 
#include <string> 
#include <vector> 
#include <iterator> 
#include <algorithm> 


int main() { 
    typedef std::ostream_iterator<double> oi_t; 
    typedef std::istream_iterator<double> ii_t; 
    std::ofstream ofs("data.bin", std::ios::in); 
    //-If file doesn't exist, create a new one now 
    if(!ofs) { 
     ofs.open("data.bin", std::ios::out|std::ios::binary|std::ios::app); 
    } 
    else { 
     ofs.close(); 
     ofs.open("data.bin", std::ios::out|std::ios::binary|std::ios::app); 
    } 

    //-Write a header consisting of length of grid subdomain and its name 
    ///* 
    const std::string grid = "Header"; 
    unsigned int olen = grid.size(); 
    ofs.write(reinterpret_cast<const char*>(&olen), sizeof(olen)); 
    ofs.write(grid.c_str(), olen); 
    //*/ 

    //-Now write the data 
    ///* 
    std::vector<double> data_out; 
    //std::vector<std::pair<int, int> > cell_ids; 
    for(int i=0; i<100; ++i) { 
     data_out.push_back(5.0*double(i) + 100.0); 
    } 
    ofs << std::setprecision(4); 
    std::copy(data_out.begin(), data_out.end(), oi_t(ofs, " ")); 
    //*/ 
    ofs.close(); 

    //-Now read the binary file; first header then data 
    std::ifstream ifs("data.bin", std::ios::binary); 
    ///* 
    unsigned int ilen; 
    ifs.read(reinterpret_cast<char*>(&ilen), sizeof(ilen)); 
    std::string header; 
    if(ilen > 0) { 
     char* buf = new char[ilen]; 
     ifs.read(buf,ilen); 
     header.append(buf,ilen); 
     delete[] buf; 
    } 
    std::cout << "Read header: " << header << "\n"; 
    //*/ 

    ///* 
    std::vector<double> data_in; 
    ii_t ii(ifs); 
    std::copy(ii, ii_t(), std::back_inserter(data_in)); 
    std::cout << "Read data size: " << data_in.size() << "\n"; 
    //*/ 
    ifs.close(); 

    //-Check the result 
    ///* 
    for(int i=0; i < data_out.size(); ++i) { 
     std::cout << "Testing input/output element #" << i << " : " 
       << data_out[i] << " " << data_in[i] << "\n"; 
    } 
    std::cout << "Element sizes: " << data_out.size() << " " << data_in.size() << 
      "\n"; 
    //*/ 
    return 0; 
} 

の問題は、私が書くと、ヘッダと、それが失敗したデータ(私はそれがその後、データを読み取らないことを確認したの両方を読んで(そして印刷)しようとすると、ヘッダーは正しく表示されます)。しかし、私が書き込みセクション(ヘッダーやデータ)のいずれかをコメントアウトすると、正しく読み上げられたことを示すその部分が表示されます。私は正しく読んでいないと確信しています。おそらくどこかでseekgの使い方が欠けているかもしれません。

+0

作品を動作するはずです。 "Read header:Header \ n Read data size:100 \ n" then 100テスト入出力... – Naddiseo

+0

ビジュアルスタジオ2010を使用して私のためにも動作します – shengy

+0

それは奇妙です。それは私にとってはうまくいかない。コードはそのままですが、サイズ0のデータを読み取るので、それに続くprintセクションでsegfaultsを出力します。私はCygwinとLinux(RHEL5)でテストしました。まだWindowsでテストしていない。 –

答えて

1

コードはうまく動作します。しかし、ファイルが正常に書き込み用に開かれたかどうかを決して確認しないので、システムで黙って失敗する可能性があります。あなたがを開いた後、あなたがそれらの線に沿ってifs

if (!ifs) { 
    std::cout << "Could not open file for reading" << std::endl; 
    return 1; 
} 

か何かを開いた後、あなたは

if (!ofs) { 
    std::cout << "Could not open file for writing" << std::endl; 
    return 1; 
} 

と同じことを追加する必要があります。また、ファイルが存在するかどうかをチェックするのはなぜですか?

+0

コメントをいただきありがとうございますが、これはデータ全体、つまりヘッダーと倍精度(私は思う)を読むという実際の問題を解決していない比較的小さな問題です。 –

+0

あなたはそれを試しましたか?投稿したコードはうまく動作しません_私はファイル 'data.bin'を開くことができません。その場合はクラッシュします。 –

+0

ありがとうございます。あなたが正しいです。 if(ofs)が失敗したとき(fail bit)に開くとクラッシュします。私はこれを修正した。それは私にいくつかのアイデアを与えます。 –

0

これは私のために

#include <iostream> 
using std::cout; 
using std::cerr; 
using std::cin; 
using std::endl; 
#include <fstream> 
using std::ifstream; 
#include <cstdint> 

int main() { 

    ifstream fin; 
    fin.open("input.dat", std::ios::binary | std::ios::in); 
    if (!fin) { 
     cerr << "Cannot open file " << "input.dat" << endl; 
     exit(1); 
    } 

    uint8_t input_byte; 
    while (fin >> input_byte) { 
     cout << "got byte " << input_byte << endl; 
    } 

    return 0; 
} 
関連する問題