2016-04-01 47 views
1

C++でバイナリファイルにオブジェクトを書き込んだときに混乱します。私はこのように、文字列をファイルに書いたとき:オブジェクトをC++でバイナリファイルに書き込む

//write a string to a binary file 
ofstream ofs("Test.txt", ofstream::binary | ofstream::app); 
string foo = "This is a long .... string." 
ofs.write((char*)&foo, sizeof(foo)); 
ofs.close(); 

しかし、それはファイルではなく、文字列自体に何か他のもの(多分ポインタ)を書きました。

私はクラスのオブジェクト(文字列メンバを持つ)を書きましたが、それはうまくいきました。

// a simple class 
class Person { 
public: 
    Person() = default; 
    Person(std::string name, int old) : fullName(name), age(old) {} 
    std::string getName() const { return this->fullName; } 
    int getAge() const { return this->ID; } 

private: 
    string fullName; 
    int age; 
}; 

int main() 
{ 
    std::ofstream ofs("Test.txt", std::ofstream::binary | std::ofstream::app); 
    Person p1("lifeisamoive", 1234); 
    ofs.write((char*)&p1, sizeof(Person)); 
    ofs.close(); 

    Person *p2 = new Person(); 
    std::ifstream ifs("Test.txt", std::ifstream::binary); 
    //output the right information 
    while(ifs.read((char*)p2, sizeof(Person))) 
     std::cout << p2->getName() << " " << p2->getAge() << std::endl; 
    else 
     std::cout << "Fail" << std::endl; 
    ifs.close(); 
    return 0; 
} 

正しい情報を出力します。

なぜですか?ありがとう。

答えて

0

personオブジェクトのメモリアドレスを読み取っています。 Personオブジェクトは、文字列オブジェクトとintオブジェクトで構成されます。プログラムが実行されている間にこれらの値をメモリから読み取ることは、=演算子を使用してオブジェクトをコピーすることと同じ意味です。

1

文字列オブジェクトには、実際のテキストが残っているヒープへのポインタが含まれています。オブジェクトをファイルに保存すると、ポインターは保存されますが、ポインターの内容は保持されません。

2番目の例では、p1からp2の実際のchar配列へのポインタを読み込み、p1がまだ存在するので、同じ名前を見ることができます。しかし、あなたはまだ同じ問題を抱えています。実際には読み込み可能な文字列をファイルに格納していませんでした。

ヒープへのポインタを持つオブジェクトをファイルに保存しないでください。キャストだけで文字列をcharポインタに変換することはできません。代わりにc_str()を使うべきです。だから、次のように試してみてください:

ofstream ofs("Test.txt", ofstream::binary | ofstream::app); 
string foo = "This is a long .... string." 
ofs.write(foo.c_str(), foo.size()); 
ofs.close(); 
+0

はい、私はそれを手に入れました。なぜクラスがPODタイプかどうかわからないときに、オブジェクトをファイルに直接書き込むことは推奨されません。ありがとうございました。 – lifeisamoive

関連する問題