0

バイナリ ファイルからの読み取りに問題があります。私の宿題は、ビデオ ライブラリ ストアのファイル システムを管理することです。

私はクラス「Client」を持っています(コードは以下にあります)。現在、write()およびread()関数がどのように機能するかを理解しようとしているだけなので、main()でそれらを「遊んで」います。

まず、ファイルを開き、60 個の空のレコードを書き込みます。次に、いくつかのクライアントをファイルに書き込みます。

ファイル内の特定の位置から別の既存のクライアントオブジェクトに1つのクライアントレコードを読み取ろうとすると、2つのレコードが読み取られます...

私はほとんどすべてを試して読みましたが、答えが見つかりませんでした。

レコードを空のクライアント オブジェクトに読み込もうとすると、バイナリ ガベージでいっぱいになります。

#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 に答える