C++ ifstream handles different sized objects

Description

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;
}



PreviousNext

Related