2017-08-15 12 views
0

構造体内に配列を格納し、構造体をバイトファイルとして保存する必要があります。問題は、配列を動的にする必要があることです。ポインタ配列の保存は、ポインタを保存するだけで、ベクターは機能しません。以下は私が使用している現在の設定例です。バイナリファイルにダイナミックアレイを格納できません

struct GenerationBase 
{ 
    //float value[];    // Will override data currently in ram 
    //float value[10];    // Dose not work as it needs to have a dynamic size 
    //float* value;     // Will only save the pointer value 
    //std::vector<float> value;  // Dose not work for some reason 
}; 

template<typename T> 
void write_to_file(std::ofstream& stream, T data) 
{ 
    stream.write(reinterpret_cast<const char*>(&data), sizeof(T)); 
} 

int main() 
{ 
    const char* file = "file.txt"; 

    GenerationBase write{}; 

    std::ofstream stream_write(file, std::ios::binary); 

    write_to_file(stream_write, write); 

    stream_write.close(); 

} 
+1

'ド/ Serialiazation'.httpの使用を検討してください://www.boost.org/doc/libs/1_36_0/libs/serialization/doc/index.html – Raindrop7

+0

のsizeof(T)は、コンパイル時のものです - あなたの配列が動的な場合はオプションではありません。 – WindyFields

+0

'ベクトル 'は単純なデータ配列より複雑です。あなたはそれのアドレスを取ることはできません。 – AndyG

答えて

0

注釈の注釈はすべて正しいものです。シリアル化にはライブラリを使用する必要があります。 protobuf、boost :: serializationは良いバイナリ形式ですが、JSONとXMLはテキスト保存に適しています。

このアプローチには根本的な問題がありますが、構造体のバイト構成はコンパイラ、エンディアン、32または64ビットアーキテクチャに依存します。つまり、C++データ構造のバイト内容をファイルに格納するだけでは意味がありません。

0

「サイズはコンパイル時ではなく実行時に決定される」という意味で動的サイズの構造体を使用する場合、構造体の最後のメンバーとしてfloat value[]のような不特定のサイズの配列を使用できます。ただし、構造体に適切なサイズのメモリを手動で割り当てる必要があります。これはCの場合であり、C++の場合もそうです。残念ながら、newはタイプを使用してランタイム値ではなく型を使用するため、オペレータnewを使用する場合は手動でサイズを定義するのはややこしいことです。だからおそらくmallocfreeを使用しますが、C++ではどこかに間違えて見えます。

より簡単な解決策は、std::vectorを使用し、構造体メモリのダンプを書き込むのではなく、ベクターの内容を書き込むことです。

とにかく、あなたが従うアプローチごとに、配列の要素数もファイルに書き込む必要があります。さもなければ、少なくとも同じ構造体を同じファイルに順番に書き込むと、ファイルに格納されている(動的な)配列の要素の数が失われる可能性があります。もちろん、読み込みプロセスではこの数値を考慮に入れて、それに応じてstructsを作成/変更する必要があります。

(1)ベクトルアプローチと(2)可変サイズの構造を持つ構造を示す次のコードを参照してください。それが何とか役立つことを願っています。

struct GenerationBase_UsingVector 
{ 
    std::vector<float> value; 

    void write(std::ofstream &w) const { 
     size_t num_elems = value.size(); 
     w.write((const char*)&num_elems, sizeof(num_elems)); 
     w.write((const char*)value.data(), num_elems*sizeof(float)); 
    } 

    void read(std::ifstream &r) { 
     size_t num_elems; 
     r.read((char *)&num_elems, sizeof(num_elems)); 
     float f; 
     while (num_elems--) { 
      r.read((char *)&f, sizeof(f)); 
      value.push_back(f); 
     } 
    } 
}; 

struct GenerationBase_PlainArray 
{ 
    size_t num_elems; 
    float value[]; 

    static GenerationBase_PlainArray* create(size_t num_elems) 
    { 
     GenerationBase_PlainArray* result = (GenerationBase_PlainArray*)malloc(sizeof(GenerationBase_PlainArray) + num_elems*sizeof(float)); 
     result->num_elems = num_elems; 
     return result; 
    } 

    static struct GenerationBase_PlainArray* newFromStream(std::ifstream &r) { 
     size_t num_elems; 
     r.read((char *)&num_elems, sizeof(num_elems)); 
     GenerationBase_PlainArray* result = GenerationBase_PlainArray::create(num_elems); 
     r.read((char *)result->value, num_elems*sizeof(float)); 
     return result; 
    } 

    void write(std::ofstream &w) const { 
     w.write((const char*)&num_elems, sizeof(num_elems)); 
     w.write((const char*)value, num_elems*sizeof(float)); 
    } 
}; 

int main() { 


    GenerationBase_UsingVector gb_vector_forwrite; 
    gb_vector_forwrite.value.push_back(1.0); 
    gb_vector_forwrite.value.push_back(2.0); 
    gb_vector_forwrite.value.push_back(3.0); 
    gb_vector_forwrite.value.push_back(4.0); 
    gb_vector_forwrite.value.push_back(5.0); 
    gb_vector_forwrite.value.push_back(6.0); 

    std::ofstream write("test.bin", std::ios::binary); 
    gb_vector_forwrite.write(write); 
    write.close(); 

    GenerationBase_UsingVector gb_vector_forread; 
    std::ifstream read("test.bin", std::ios::binary); 
    gb_vector_forread.read(read); 
    read.close(); 

    for (auto f : gb_vector_forread.value) { 
     cout << f << endl; 
    } 

    GenerationBase_PlainArray* gb_array_forwrite = GenerationBase_PlainArray::create(6); 
    gb_array_forwrite->value[0] = 1.0; 
    gb_array_forwrite->value[1] = 2.0; 
    gb_array_forwrite->value[2] = 3.0; 
    gb_array_forwrite->value[3] = 4.0; 
    gb_array_forwrite->value[4] = 5.0; 
    gb_array_forwrite->value[5] = 6.0; 

    std::ofstream write2("test2.bin", std::ios::binary); 
    gb_array_forwrite->write(write2); 
    write2.close(); 
    free(gb_array_forwrite); 

    std::ifstream read2("test2.bin", std::ios::binary); 
    GenerationBase_PlainArray *gb_array_forread = GenerationBase_PlainArray::newFromStream(read2); 
    read2.close(); 

    for (int i=0; i<gb_array_forread->num_elems; i++) { 
     cout << gb_array_forread->value[i] << endl; 
    } 
    free(gb_array_forread); 

} 
関連する問題