0

私の問題は次のようになります。「Register」というクラスがあります。「trainName」という文字列属性とそのセッターがあります。

class Register {

 private:
    string trainName;

 public:
    string getTrainName();
};

実のところ、長くなりますが、これを簡単にしたいと思います。

別のクラスでは、いくつかの Register オブジェクトをバイナリ ファイルにコピーし、事前に trainName を設定しています。

Register auxRegister = Register();   
auxRegister.setName("name");

for(int i = 0; i < 10; i++) {

  file.write(reinterpret_cast<char*>(&auxRegister),sizeof(Register));

}

後で、バイナリ ファイルからレジスタを取得しようとします。

Register auxRegister = Register();

while(!file.eof()) { //I kwnow this is not right. Which is the right way?

    file.read(reinterpret_cast<char*>(&auxRegister), sizeof(Register));
}

動作しないことが発生します。実際、Register にはより多くの属性 (int 型) があり、それらを正常に取得できますが、文字列の場合はそうではありません。

私は何か間違ったことをしていますか?バイナリ ファイルと文字列を操作する際に考慮すべき点はありますか?

どうもありがとうございました。

4

2 に答える 2

2

このstd::stringクラスには、文字列が (他のメンバー変数と共に) 格納されるバッファーへのポインターが含まれています。文字列バッファ自体はクラスの一部ではありません。したがって、クラスのインスタンスの内容を書き出すことは機能しません。そのようにすると、文字列はファイルにダンプするものの一部にはならないからです。文字列へのポインタを取得してそれを書き込む必要があります。

Register auxRegister = Register();   
auxRegister.setName("name");
auto length = auxRegister.size();

for(int i = 0; i < 10; i++) {
  file.write( auxRegister.c_str(), length );
  // You'll need to multiply length by sizeof(CharType) if you 
  // use a wstring instead of string
}

後で文字列を読み取るには、ファイルに書き込まれたバイト数を追跡​​する必要があります。または、ファイル形式に応じて、ファイル自体からその情報を取得することもできます。

std::unique_ptr<char[]> buffer( new char[length + 1] );
file.read( buffer, length );

buffer[length] = '\0'; // NULL terminate the string
Register auxRegister = Register();

auxRegister.setName( buffer );
于 2012-05-14T20:07:27.340 に答える
2

この方法で文字列を書くことはできません。ほとんどの場合、まったくシリアル化できないいくつかの構造体やその他のバイナリへのポインターが含まれているためです。独自のシリアル化関数を記述し、文字列の長さ + バイト (たとえば) を記述するか、シリアル化の問題を解決できるprotobufなどの完全なライブラリを使用する必要があります。

編集:プラエトリアンの答えを参照してください。私よりもはるかに優れています(この編集時のスコアは低くても)。

于 2012-05-14T19:51:53.573 に答える