在c ++中从二进制文件中读取对象的问题

时间:2012-07-14 14:53:13

标签: c++ file binary

我从二进制文件读取时遇到问题。我的作业是管理视频库商店的文件系统。

我有一个类“Client”(代码在下面),现在我只是想了解write()和read()函数是如何工作的,所以我在我的主要“玩”它们( )。

首先,我打开一个文件并将60条空记录写入其中。然后我在文件中写了几个客户端。

当我尝试读取一个客户端记录时,从文件中的给定位置到另一个现有客户端对象 - 它读取两条记录......

我几乎尝试过所有内容并且没有找到答案。

如果我试图将记录读入一个空的客户端对象,它就会充满二进制垃圾。

#pragma once
#include <time.h>
#include <string>
#include <iostream>
using namespace std;

class Client
{
    private:
        char id[10];                        //client info
        char name[20];
        char address[40];
        char phoneNum[11];                  
        time_t startMembership;             //variable that represents the beginning of the membership in the library
        time_t endMembership;               //variable that represents the end of the membership in the library     
        int fines;


    public:
        Client() {};
        Client(char id[10],char name[20],char address[40],char phone[10],int fines);    //constructor 
        int     getFines()                              {return this->fines;}                                           //getters
        char*   getId()                                 {return this->id;}
        void    setName(char* newName)                  {strcpy(this->name,newName);}
        void    setId(char* newId)                      {strcpy(this->id,newId);}                                       //setters
        void    setAddress(char* newAddress)            {strcpy(this->address,newAddress);}
        void    setPhone(char* newPhone)                {strcpy(this->phoneNum,newPhone);}
        void    setStartMembership(time_t newStartDate) {this->startMembership = newStartDate;}
        void    setEndMembership(time_t newEndDate)     {this->endMembership = newEndDate;}
        void    setFines(int newFines)                  {this->fines = newFines;}
        bool    finesChecking();                                                                                        //true= need to pay

        friend ostream& operator<<(ostream& os, const Client& c);
        ~Client();                                                                                                  //distructor    
};


#include "Client.h"

/**
* Constructor
*/
Client::Client(char id[10],char name[20],char address[40],char phone[10],int fines)
{
    strcpy(this->id,id);
    strcpy(this->name,name);
    strcpy(this->address,address);
    strcpy(this->phoneNum,phone);
    this->fines = fines;
    time(&this->startMembership);       // the time in the binary file will be represented as raw time
    time(&this->endMembership);         
    this->endMembership += 30*24*60*60; // set the expiration date of the membership (1 month)
}

ostream& operator<<(ostream& os, const Client& c)
{
    os<<"ID: "<<c.id<<endl;
    os<<"Name: "<<c.name<<endl;
    os<<"Phone#: "<<c.phoneNum<<endl;
    os<<"Address: "<<c.address<<endl;
    os<<"Member Since: "<<ctime(&c.startMembership);
    os<<"Membership Exp: "<<ctime(&c.endMembership);
    os<<"Fines: "<<c.fines<<" ILS"<<endl;
    return os;
}

/**
* Distructor
*/
Client::~Client()
{
    delete[] this->address;
    delete[] this->id;
    delete[] this->name;
    delete[] this->phoneNum;
}


#include <iostream>
#include <fstream>
#include <string>
#include <time.h>
#include "Menu.h"
#include "MovieCatalog.h"
#include "Client.h"

using namespace std;

int main()
{
    /*Menu menu;
    menu.StartMenu();*/

    Client *first, *second, *third, *fourth, *fifth;
    first = new Client("1","first","Lod","1",50);
    second = new Client("2","second","Herzelia","2",50);
    third = new Client("3","third","Holon","3",50);
    fourth = new Client("4","fourth","Haifa","4",50);
    fifth = new Client("5","fifth","Raanana","5",50);

    fstream file;
    Client blankClient;
    blankClient.setId("0");

    file.open("example.bin", fstream::out | fstream::binary);
    streampos pos;
    for(int i=1; i<=60; i++)
    {
        file.write((char*)&blankClient, sizeof(Client));
    }
    file.close();

    file.open("example.bin", fstream::out | fstream::binary);
    file.write((char*)&first,sizeof(Client));
    file.write((char*)&second,sizeof(Client));
    file.write((char*)&third,sizeof(Client));
    //put fourth and fifth @ 10th and 11th records
    file.seekp(sizeof(Client)*10,ios_base::beg);
    file.write((char*)&fourth,sizeof(Client));
    file.write((char*)&fifth,sizeof(Client));
    file.close();

    file.open("example.bin", fstream::in | fstream::binary);
    //put the "get" pointer on the 11th record (where "fifth" is located)
    file.seekg(sizeof(Client)*11,ios_base::beg);
    //read "fifth" object into "second" object
    file.read((char*)&second,sizeof(Client));
    file.close();
    cout<<*first;
    cout<<*second;
    //here you can see that it takes "fifth" and put it into "second", and the record prior to fifth ("fourth"), into "first"
    return 0;
}

1 个答案:

答案 0 :(得分:2)

给出声明:first = new Client("1","first","Lod","1",50);

您的写作方法不正确:

file.write((char*)&first,sizeof(Client));
file.write((char*)&second,sizeof(Client));
...

所以你要编写指针而不是对象本身的地址,使它像:

 file.write((char*)first,sizeof(Client));
 file.write((char*)second,sizeof(Client));
 ...

相同的行:

file.read((char*)&second,sizeof(Client)); -> file.read((char*)second,sizeof(Client));

你的析构函数也不正确Client::~Client(),而你的情况并不需要