0

私はここで少し複雑な状況にいます。ベクトルの構造体をファイルに保存し、しばらくしてから読みたいと思います。しかし、問題は読み方です。保存したファイルからすべてのベクトルを構造体に入力する方法がわかりません。

 struct TDNATable{


        std::vector<String>GenomOne;
        std::vector<String>GenomeL;
        std::vector<String>GenomeER;
        std::vector<String>GenomeRET;
        std::vector<String>GenomeSEL;

    };

    std::vector<TDNATable> DnaTbl;



//PSEUDO CODE:
    //For example simple writing could be
    ofstream file("C:\\Users\\User11\\Desktop\\SNF_TBL.INI", ios::binary);
    file.write((char*)&DnaTbl, sizeof(DnaTbl));

//Problem comes with reading 
 // impl
    ifstream file("C:\\Users\\User11\\Desktop\\SNF_TBL.INI",
        std::ifstream::binary);

    // get pointer to associated buffer object
    std::filebuf* pbuf = file.rdbuf();

    // get file size using buffer's members
    std::size_t size = pbuf->pubseekoff(0, file.end, file.in);
    pbuf->pubseekpos(0, file.in);

    // allocate memory to contain file data
    char* buffer = new char[size];

    // get file data
    pbuf->sgetn(buffer, size);

    file.close();


for (int i = 0; i < SnfTbl.size(); i++) {

//Back inserter can be used only with 1D vector        
std::copy(buffer, buffer +sizeof(buffer),
            std::back_inserter(SnfTbl[i].GenomeL);

        std::copy(buffer, buffer +sizeof(buffer),
            std::back_inserter(SnfTbl[i].GenomeER));



    }

    RefreshDFSGrid();


    delete[]buffer;
    file.close();

ブースト/シリアル化を試しましたが、成功しませんでした。

このdsをエレガントな方法で保存/ロードする方法を知っていますか? ありがとう!

4

2 に答える 2

3

ブーストは、簡単なタスクにはやり過ぎかもしれません。私自身のコードでは、ある種のストリーム クラスを使用してその問題を解決しました。私はそのようにしました:

  1. と で抽象基本クラスを宣言virtual Read(buffer, byteCount) = 0virtual Write(buffer, byteCount) = 0ます。以下の図では、IArchiveIIArchiveOがそのような基本クラスです。

  2. 組み込み型の場合、必要に応じて単に Read() と Write() を呼び出す and を提供しますoperator <<operator >>

  3. vector / string / ... などのライブラリ型の場合、基本型演算子に基づいて構築された非メンバー テンプレート演算子を提供します (たとえば、生の Read / Write を呼び出さなくなりました)。

たとえば、ベクトルを処理する方法は次のとおりです。

template <class T>
IArchiveO& operator << (IArchiveO& a_Stream, const std::vector<T>& a_Vector)
{
    a_Stream << a_Vector.size();
    for (size_t i = 0; i < a_Vector.size(); i++)
    {
        a_Stream << a_Vector[i];
    }

    return a_Stream;
}

template <class T>
IArchiveI& operator >> (IArchiveI& a_Stream, std::vector<T>& a_Vector)
{
    a_Vector.clear();

    size_t contSize = 0;
    a_Stream >> contSize;

    a_Vector.resize(contSize);
    for (size_t i = 0; i < contSize; i++)
    {
        a_Stream >> a_Vector[i];
    }

    return a_Stream;
}

独自の非ライブラリ型の場合は、演算子を同じ方法で提供します。たとえば、コードは次のようになります。

IArchiveI& operator >> (IArchiveI& a_Stream, TDNATable& a_Value)
{
    a_Stream >> a_Value.GenomOne;
    a_Stream >> a_Value.GenomeL;
    a_Stream >> a_Value.GenomeER;
    a_Stream >> a_Value.GenomeRET;
    a_Stream >> a_Value.GenomeSEL;
    return a_Stream;
}
  1. 基本クラスから継承し、ファイルの読み取り/書き込みなどのストレージを提供するクラスを作成します。virtual Read(buffer, byteCount)とをオーバーロードするだけですvirtual Write(buffer, byteCount)

  2. 最後に、ストレージ クラスのインスタンスを構築し、配列全体を一度にシリアル化します (このコードでは、CFileArchiveO は IArchiveO から継承され、Write() をオーバーロードします)。 CFileArchiveO ar(...); ar << DnaTbl;

トリックは、コンパイラが各型の演算子を持っている場合、たとえそれがvector<vector<vector<string>>>

于 2013-08-19T14:26:07.910 に答える
0

std::vectorデータの挿入時にメモリを割り当てます。

そう

file.write((char*)&DnaTbl, sizeof(DnaTbl));

の「メタデータ」のみを保存し、std::vector<TDnaTbl>挿入したデータは除外します。データはメモリの別の場所に保存されます。ベクトルを繰り返し処理し、要素数と要素データを手動で保存する必要があります。

于 2013-08-19T13:54:54.843 に答える