2016-09-22 40 views
-4
#include<iostream> 
#include<string> 
#include<fstream> 
using namespace std; 
class telephone 
{ 
    string name; 
    long number; 
    public : 
    void getdata(); 
    void display(); 
}; 
void telephone :: getdata() 
{ 
    cout<<"Enter the name : "; 
    getline(cin,name); 
    cout<<"Enter the number : "; 
    cin>>number; 
} 
void telephone :: display() 
{ 
    cout<<"1. Name : "<<name<<endl; 
    cout<<"2. Number : "<<number<<endl; 
} 
int main() 
{ 
    fstream f; 
    telephone p,q; 
    f.open("dir.txt",ios::out); 
    p.getdata(); 
    f.write((char*)&p,sizeof(telephone)); 
    f.close(); 
    f.open("dir.txt",ios::in); 
    while(f.read((char*)&q,sizeof(telephone))) 
    { 
    q.display(); 
    } 
    f.close(); 
    return 0; 
} 

私はこのコードを書いて、クラスオブジェクトのファイルからデータを読み込みました。これは出力を表示しますが、何らかのエラーを示しています。C++でのファイル操作

OUTPUT:私はそれは同じerror.Pleaseはこのエラーを取り除くために私を助けて示したの.datが、.TXT、.binファイルなどのファイル拡張子を使用して試してみました

Enter the name : rahul 
Enter the number : 234546 
1. Name : rahul 
2. Number : 234546 
*** Error in `./a.out': double free or corruption (fasttop): 0x08f861a8 *** 
Aborted (core dumped) 

+2

C++を使用している場合は、 'ifstream'、' ofstream'、 '<<' and '>>'演算子を使用してください。 – AndyG

+2

文字列をオブジェクトとして持つためシリアル化が必要 – Raindrop7

+2

[C++の同じクラスの複数のオブジェクトを読み書きできます](http://stackoverflow.com/questions/18186701/c-read-and-write-multiple-objects同じクラスの) – Raindrop7

答えて

1

telephoneをバイナリBLOBとしてファイルに書き込むことはできません。 telephoneにはnameが含まれ、名前はstd::stringです。 std::stringには通常、それが表す文字列データは含まれません。それは文字列データへのポインタを含んでいます。あなたは

f.write((char*)&p,sizeof(telephone)); 

あなたが実際にファイルに書いたものをするとき

だから、文字列データが、文字列データへのポインタではありませんでした。これは

f.read((char*)&q,sizeof(telephone)); 

qpのポインタをリードバックし、それが同一の文字列データでそのpq両方の点を意味することを意味します。これは悪いです。

ときpまたはqはスコープの外に出ると、破壊され、彼らはnameを破壊し、name、良い小さなstd::stringのように、それがで指すメモリを解放します。これにより、解放されたメモリを指すstd::stringを含む他のオブジェクトが残され、遅かれ早かれ他のオブジェクトが使用されてundefined behaviourが呼び出されるか、破棄されて以前に解放されたメモリを解放しようとします。これは、「ダブルフリー」というエラーメッセージで意味されています。同じメモリが2回解放されました。 qが削除された場合は、あなたの場合は

pq解放メモリの前にその両方 pと、無効なメモリ位置を指し pを離れる時 qポイント。数ナノ秒後に pが削除され、 pは既に解放されたメモリを解放できません。

この問題を回避するには、std::stringの内容がファイルに書き込まれていることを確認してから、それを読み取る必要があります。これはserializationと呼ばれます。この問題への

典型的なソリューションは<<でテキスト形式のファイルにデータを書き込むと

class telephone 
{ 
    string name; 
    long number; 
    public : 
    void getdata(); 
    void display(); 
    friend std::istream & operator<<(std::istream & out, const telephone & tp); 
    friend std::ostream & operator>>(std::ostream & in, telephone & tp); 
}; 
(あなたのクラスの <<>>演算子を実装する必要もある) >>に戻ってそれを読み取ることがあります

は、これらの機能の書き込みは、おそらくこの割り当ての時点でクラス

class telephone 
{ 
    string name; 
    long number; 
    public : 
    void getdata(); 
    void display(); 
    bool serialize(std::iostream & out); 
    bool deserialize(std::iostream & in); 
}; 

にシリアライズ機能を追加したり、私はここで停止します。心配しないでください。両方のアプローチは、問題がある場合、オンラインで非常によく文書化されています。最初のオプションから始めることをお勧めします。あなたが間違っているかどうかを確認するためにテキストファイルを読むことができるので、デバッグがずっと簡単です。

+0

ありがとう。しかし、オーバーロードされた定義を書く方法<< and >>演算子関数。 –

+0

基本的なスケルトンとイデオロギーについては、http://stackoverflow.com/questions/4421706/operator-overloadingを参照してください。私がカバーしない関数の勇気は、基本的に 'in >> phone.name'のようなものです – user4581301