0

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

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

首先,我打开一个文件并将 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;
}
4

1 回答 1

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(),而不是你的情况不需要

于 2012-07-14T15:36:58.203 回答