2017-02-13 25 views
1

std::vectorstd::complex<float>をバイナリファイルに格納し、後でこのデータをstd :: vectorに再度ロードします。私はSOに同様の質問をチェックし、次のコードを思い付いていますstd :: complex値のバイナリファイルへの書き込み/読み込み

#include <complex> 
#include <iostream> 
#include <memory> 
#include <fstream> 
#include <iterator> 
#include <random> 
#include <vector> 

using namespace std; 
typedef vector<complex<float>> complex_vector; 


float get_random(){ 
    static std::default_random_engine e; 
    static std::uniform_real_distribution<> dis(-10, 10); 
    return dis(e); 
} 

int main(){ 
    // Random number generator 
    srand(static_cast<unsigned> (time(0))); 

    // Create a vector with 25 random complex<float> values 
    std::shared_ptr<vector<complex<float>>> buffer = std::make_shared<vector<complex<float>>>(); 
    for(unsigned int i=0; i<25; i++){ 
     buffer->push_back(complex<float>(get_random(), get_random())); 
    } 

    // Write those values into a binary file 
    std::string binFileName = "aux.bin"; 
    std::ofstream rawFile(binFileName, std::ios::binary); 
    for(unsigned int i=0; i<buffer->size(); i++){ 
     rawFile.write(reinterpret_cast<const char*>(&buffer->at(i)), sizeof(complex<float>)); 
    } 
    rawFile.close(); 

    // Load the binary file into the buffer 
    std::ifstream input(binFileName, std::ios::binary); 
    complex_vector auxBuffer{std::istream_iterator<complex<float>>(input), std::istream_iterator<complex<float>>()}; 
    unsigned int samplesRead = auxBuffer.size(); 
    std::cout << samplesRead; 

    return 0; 
} 

出力:

0 

私は何をしないのですか?

EDIT: NathanOliverの答えの後、これは私のコードは、今どのように見えるかです:

#include <complex> 
#include <iostream> 
#include <memory> 
#include <fstream> 
#include <iterator> 
#include <random> 
#include <vector> 

using namespace std; 
typedef vector<complex<float>> complex_vector; 


float get_random(){ 
    static std::default_random_engine e; 
    static std::uniform_real_distribution<> dis(-10, 10); 
    return dis(e); 
} 

int main(){ 
    // Random number generator 
    srand(static_cast<unsigned> (time(0))); 

    // Create a vector with 25 random complex<float> values 
    std::shared_ptr<complex_vector> buffer = std::make_shared<complex_vector>(); 
    for(unsigned int i=0; i<25; i++){ 
     buffer->push_back(complex<float>(get_random(), get_random())); 
    } 

    // Write those values into a binary file 
    std::string binFileName = "aux.bin"; 
    std::ofstream rawFile(binFileName, std::ios::binary); 
    rawFile.write(reinterpret_cast<const char*>(buffer->size()), sizeof(buffer->size())); 
    rawFile.write(reinterpret_cast<const char*>(buffer->data()), sizeof(std::complex<float>) * buffer->size()); 
    rawFile.close(); 

    // Load the binary file into the buffer 
    std::ifstream input(binFileName, std::ios::binary); 
    complex_vector::size_type nSamples; 
    input.read(reinterpret_cast<char*>(nSamples), sizeof(complex_vector::size_type)); 
    std::cout << nSamples; 
    complex_vector *destination = new complex_vector(25); 
    input.read(reinterpret_cast<char*>(destination->data()), sizeof(std::complex<float>) * nSamples); 

    return 0; 
} 

が、私は関数を記述するために最初の呼び出しでSIGSEGVを取得しています。

また、なぜ私が書くのか分かりませんが、私は読む必要があります。

+0

おそらく 'std :: ios :: out'と' std :: ios :: in'フラグがありません。ファイルが実際に作成され、データが含まれているかどうか確認しましたか? – paddy

+2

バイナリ書き込みとフォーマット読み取りとを混在させることはできません。データを '書き込み 'する場合は、データを'読み込む'必要があります。より簡単にするには、まずベクトルの大きさを '書く 'ようにして、それを'読み込む'ことができ、データを '読み込む'ことができるように記憶域を割り当てます。 – NathanOliver

+0

'' srand'と 'std :: default_random_engine'を混ぜて使ってはいけません:) –

答えて

1

バイナリ書き込みと、現在実行中のフォーマット読み取りとを混在させることはできません。ファイルがバイナリモードで開かれていても

complex_vector auxBuffer{std::istream_iterator<complex<float>>(input), std::istream_iterator<complex<float>>()}; 

はオペレーターを呼び出す>>of複雑>and notwhich is what you should use if you write the data with write`をお読みください。

これを解決するには2通りの方法があります。

for (const auto& e : *buffer) 
    rawFile << e << "\n"; // or space or any other white space delimiter 

のように書式設定された書き込みを行うことができます。

あなたの他のオプションは、それが多くのクリーナーが、場合に見えるように私は、最初のオプションを好きwriteベクトルの大きさとベクトルの内容と、その後read両方のバック

// write the size of the vector 
rawFile.write(reinterpret_cast<const char*>(&buffer->size()), sizeof(buffer->size())); 
// write the whole contents of the vector in one go 
rawFile.write(reinterpret_cast<const char*>(buffer->data()), sizeof(std::complex<float>) * buffer->size()); 

// and then to read it back in we get the size 
complex_vector::size_type size; 
input.read(reinterpret_cast<char*>(&size), sizeof(size)); 
// construct a vector of that size 
complex_vector auxBuffer(size); 
// and then read the data back into the vector 
input.read(reinterpret_cast<char*>(auxBuffer.data()), sizeof(std::complex<float>) * auxBuffer->size()); 
個人的に

のような業者にありますこれは性能に敏感で、バイナリモードは一般的に高速です。

+0

出力ファイルのサイズが大きすぎるためバイナリにする必要があります。 2番目のオプションはコンパイルされません。 'const char *'から 'std :: basic_istream :: char_type * {aka char *}' [-fpermissive](最初の読み込み呼び出し時)への無効な変換また、ここで指定したように、なぜ私が試したように動作しないのか分かりません:http://stackoverflow.com/a/5420568/808091 –

+0

@RomanRdgz私はコードに誤りがありました。 'reinterpret_cast 'を使う必要があり、 'reinterpret_cast 'を使う必要はありません。コードが更新されました。 – NathanOliver

+0

まだ動作していないよう:http://cpp.sh/7fhuzプラス、私の地元のコードでは、私が最初の書き込みで、あなたがファイルを作成することはできませんとC++シェル上で動作するつもりはない –

関連する問題