Reputation: 55
I have a problem with reading from binary files. My homework is to manage a file system of a video library store.
I have a class "Client" (the code is below), and right now I am only trying to understand how the write() and read() functions work, so I am "playing" with them in my main().
First I am opening a file and writing 60 empty records into it. Then I am writing a few clients into the file.
when I try to read one client record, from a given position in the file into another existing client object - it reads two records...
I have tried and read almost everything and I haven't found an answer.
If I am trying to read a record into an empty client object, it is full of binary garbage.
#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;
}
Upvotes: 0
Views: 3516
Reputation: 5322
given declaration : first = new Client("1","first","Lod","1",50);
Your writing method is incorrect:
file.write((char*)&first,sizeof(Client));
file.write((char*)&second,sizeof(Client));
...
so you're writing addresses of pointer not object itself, make it like :
file.write((char*)first,sizeof(Client));
file.write((char*)second,sizeof(Client));
...
same for line :
file.read((char*)&second,sizeof(Client)); -> file.read((char*)second,sizeof(Client));
also you're destructor is incorrect Client::~Client()
, rather you don't need in your case
Upvotes: 2