2012-07-14 65 views
0

從二進制文件讀取時遇到問題。我的作業是管理視頻庫商店的文件系統。我有一個類「客戶端」(代碼如下),現在我只是想了解write()和read()函數是如何工作的,所以我在我的主要「玩」與他們()。從C++中的二進制文件讀取對象時發生的問題

首先我打開一個文件,並將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

請給我們一個http://www.sscce.org。否則,我幾乎可以確保沒有人會願意閱讀所有這些。把它分解成更小的片斷。 – Drise 2012-07-14 14:54:55

+1

它看起來像我正在讀取數據到客戶端指針的位置,而不是該位置指向的位置。 '第一','第二'等已經是指針 - 只需將它們傳遞給您的讀/寫調用,而不是將它們的地址傳遞給它們。你的代碼中似乎有'&'的盈餘:) – 2012-07-14 15:02:56

回答

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(),而你並不需要在你的情況