Search code examples
c++classinheritanceifstream

C++ Using different subclasses based on part of input


I have some issues solving a task from class. My algorithm for solving the issues is working fine, but my problem is to read data from 3 different text files into 2 different classes.

Now the 1st text file "hours.txt" gives a string id and hour int, like so:

adam1;170
eve2;170

so, separated by a ";". The next file contains the same id as before and name, taxid, type, and according to type: wage if PH, or salary and ovtwage if IS.

adam1;Adam Driver;12345678;PH;5;
eve2;Eve Assistant;23456789;IS;650;10

The 3rd file contains only the int 160, which is defined as generalWorkingHours. Now to where my problems are arising. I have experience in reading data from 1 file into 1 class but in this case I have to read data to 2 classes, ph and is depending on the type of the id's(adam1 and eve2). I have been provided two classes like this :

#ifndef IS_H
#define IS_H
#include "Employee.h"
#include <iostream>

using namespace std;

class is: public Employee
{
    public:
        is();
        virtual ~is();
        void setSalary(int salary);
        int getSalary();
        void setOvtWage(int ovtWage);
        int getOvtWage();
    protected:
    private:
        int salary;
        int ovtWage;
};

#endif // IS_H

and

#ifndef PH_H
#define PH_H
#include "Employee.h"
#include <iostream>

using namespace std;

class ph: public Employee
{
    public:
        ph();
        virtual ~ph();
        void setWage(int wage);
        int getWage();
    protected:
    private:
        int wage;
};

#endif // PH_H

Both of these classes contain the public "Employee"

#ifndef EMPLOYEE_H
#define EMPLOYEE_H

#include <iostream>

using namespace std;

class Employee
{
    public:
        Employee();
        virtual ~Employee();
        void setId(string id);
        string getId();
        void setName(string name);
        string getName();
        void setTaxId(string taxid);
        string getTaxId();
        void setType(string type);
        string getType();
        void setHours(int hours);
        int getHours();
    protected:
    private:
        string id;
        string name;
        string taxid;
        string type;
        int hours;
};

#endif // EMPLOYEE_H

Now, usually I would create a function to read a file, and one to parse each line like so:

void Resolver::parseTextLine(string tmp, int & carCnt, carList X[]){
    std::size_t found;

    found=tmp.find(";");
    if (found!=string::npos) {
        X[carCnt].point=tmp.substr(0,found);
        tmp=tmp.substr(found+1);
    }

    found=tmp.find(";");
    if (found!=string::npos) {
        X[carCnt].license=tmp.substr(0,found);
        tmp=tmp.substr(found+1);
    }

    found=tmp.find(";");
    if (found!=string::npos) {
        X[carCnt].time=atoi(tmp.substr(0,found).c_str());
        tmp=tmp.substr(found+1);
    }

    carCnt++;
}


void Resolver::readDataFromFiles(string carFile, int & carCnt, carList X[]){

    carCnt=0;

    ifstream finS(carFile.c_str(),ios::in);

    bool first=true;
    while (!finS.eof()) {
        string tmp="";
        getline(finS,tmp);
        if (tmp!="") {
            if (first) {
                first=!first;
            } else {
                parseTextLine(tmp,carCnt,X);
            }
        }
    }

    finS.close();
}

NOTE: this is just an idea of how I am trying to solve it, but I have no experience with using multiple files and classes. All the functions are premade and I just need to patch it together somehow.


Solution

    1. Assuming all the ids are unique, create a map<string, Employee*> Emp; This will store information of all the employee indexed by id as key ("adam1", "eve2") and object as value.

    ["adam1"] => [object of ph]

    ["eve2"] => [object of is]

    1. Now, read file_2 which contains information about PH and IS. Now for each line read you will have all the components separated by ";" appearing in the line. After separating components from the line, you should be able to decide (using type) which derived class should be instantiated.

      if(type == PH)
      {
          //suppose id = "adam"
          ph *pEmployeePH = new ph(); 
          //also set wage 
          //insert [id] in map Emp if not already present
      }
      if(type == IS) 
      {
          //suppose id is now "eve2"
          is *pEmployeeIS = new is();
          //also set salary and ovtwage
          //insert [id] in map Emp if not already present
      }
      
    2. Once you have your map ready, now read file_1. Now for each line read you will have 2 components separated by ";" appearing in the line. After separating components from the line, you should be able to decide (using id) which element of map Emp you should access/modify in order to set the hours. Suppose id is "adam1" and hours=170, so now check whether map contains ["adam1"] and if does contain then set the hours as follows: Emp[id].setHours(hours);