C++ ifstream handles different sized objects
#include <fstream> //for file-stream functions #include <iostream> #include <typeinfo> //for typeid() using namespace std; #include <process.h> //for exit() const int LEN = 32; //maximum length of last names const int MAXEM = 100; //maximum number of Employees enum Employee_type {tManager, tScientist, tProgrammer}; class Employee //Employee class { private:/* w ww .j a v a 2s . co m*/ char name[LEN]; //Employee name unsigned long number; //Employee number static int n; //current number of Employees static Employee* arrap[]; //array of ptrs to emps public: virtual void getdata() { cin.ignore(10, '\n'); cout << " Enter last name: "; cin >> name; cout << " Enter number: "; cin >> number; } virtual void putdata() { cout << "\n Name: " << name; cout << "\n Number: " << number; } virtual Employee_type get_type(); //get type static void add(); //add an Employee static void display(); //display all Employees static void read(); //read from disk file static void write(); //write to disk file }; //static variables int Employee::n; //current number of Employees Employee* Employee::arrap[MAXEM]; //array of ptrs to emps //Manager class class Manager : public Employee { private: char title[LEN]; //"vice-president" etc. double dues; //golf club dues public: void getdata() { Employee::getdata(); cout << " Enter Title:C++ "; cin >> title; cout << " Enter golf club dues: "; cin >> dues; } void putdata() { Employee::putdata(); cout << "\n Title:C++ " << title; cout << "\n Golf club dues: " << dues; } }; //Scientist class class Scientist : public Employee { private: int pubs; //number of publications public: void getdata() { Employee::getdata(); cout << " Enter number of pubs: "; cin >> pubs; } void putdata() { Employee::putdata(); cout << "\n Number of publications: " << pubs; } }; //Programmer class class Programmer : public Employee { }; //add Employee to list in memory void Employee::add() { char ch; cout << "'m' to add a Manager" "\n's' to add a Scientist" "\n'l' to add a Programmer" "\nEnter selection: "; cin >> ch; switch(ch) { //create specified Employee type case 'm': arrap[n] = new Manager; break; case 's': arrap[n] = new Scientist; break; case 'l': arrap[n] = new Programmer; break; default: cout << "\nUnknown Employee type\n"; return; } arrap[n++]->getdata(); //get Employee data from user } //display all Employees void Employee::display() { for(int j=0; j<n; j++) { cout << (j+1); //display number switch( arrap[j]->get_type() ) //display type { case tManager: cout << ". Type: Manager"; break; case tScientist: cout << ". Type: Scientist"; break; case tProgrammer: cout << ". Type: Laborer"; break; default: cout << ". Unknown type"; } arrap[j]->putdata(); //display Employee data cout << endl; } } //return the type of this object Employee_type Employee::get_type() { if( typeid(*this) == typeid(Manager) ) return tManager; else if( typeid(*this)==typeid(Scientist) ) return tScientist; else if( typeid(*this)==typeid(Programmer) ) return tProgrammer; else { cerr << "\nBad Employee type"; exit(1); } return tManager; } //write all current memory objects to file void Employee::write() { int size; cout << "Writing " << n << " Employees.\n"; ofstream ouf; //open ofstream in binary Employee_type etype; //type of each Employee object ouf.open("EMPLOY.DAT", ios::trunc | ios::binary); if(!ouf) { cout << "\nCan't open file\n"; return; } for(int j=0; j<n; j++) //for every Employee object { etype = arrap[j]->get_type(); ouf.write( (char*)&etype, sizeof(etype) ); switch(etype) //find its size { case tManager: size=sizeof(Manager); break; case tScientist: size=sizeof(Scientist); break; case tProgrammer: size=sizeof(Programmer); break; } //write Employee object to file ouf.write( (char*)(arrap[j]), size ); if(!ouf) { cout << "\nCan't write to file\n"; return; } } } //read data for all Employees from file into memory void Employee::read() { int size; //size of Employee object Employee_type etype; //type of Employee ifstream inf; //open ifstream in binary inf.open("EMPLOY.DAT", ios::binary); if(!inf) { cout << "\nCan't open file\n"; return; } n = 0; //no Employees in memory yet while(true) { //read type of next Employee inf.read( (char*)&etype, sizeof(etype) ); if( inf.eof() ) //quit loop on eof break; if(!inf) //error reading type { cout << "\nCan't read type from file\n"; return; } switch(etype) { //make new Employee case tManager: //of correct type arrap[n] = new Manager; size=sizeof(Manager); break; case tScientist: arrap[n] = new Scientist; size=sizeof(Scientist); break; case tProgrammer: arrap[n] = new Programmer; size=sizeof(Programmer); break; default: cout << "\nUnknown type in file\n"; return; } //read data from file into it inf.read( (char*)arrap[n], size ); if(!inf) //error but not eof { cout << "\nCan't read data from file\n"; return; } n++; //count Employee } cout << "Reading " << n << " Employees\n"; } int main() { char ch; while(true) { cout << "'a' -- add data for an Employee" "\n'd' -- display data for all Employees" "\n'w' -- write all Employee data to file" "\n'r' -- read all Employee data from file" "\n'x' -- exit" "\nEnter selection: "; cin >> ch; switch(ch) { case 'a': //add an Employee to list Employee::add(); break; case 'd': //display all Employees Employee::display(); break; case 'w': //write Employees to file Employee::write(); break; case 'r': //read all Employees from file Employee::read(); break; case 'x': exit(0); //exit program default: cout << "\nUnknown command"; } } return 0; }