C++ Using different subclasses based on part of input - c++

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.

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

Related

Cannot display file(related to classes)

So I am trying to read in a file using private class variables. I am unsure how to display the file. There might be another way to do this, but this is what I could think of. Note, its my first project using classes and private and public/private members. Was I on the right path atleast? I keep getting an error for the int main function. How can I fix it?
This is my main:
#include "Record.h"
#include <sstream>
int main ()
{
Record employee;
ifstream myFile;
myFile.open("Project 3.dat");
string str;
int i=0;
if (myFile.is_open())
{
while (getline(myFile, str))
{
istringstream ss(str);
ss >> employee.get_name(str) >> employee.get_id(stoi(str)) >>
employee.get_rate(stoi(str)) >> employee.get_hoursWorked(stoi(str));
}
}
return 0;
}
This is my header:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Record
{
private:
string name;
int id;
double rate;
double hours;
public:
Record();
Record (string n, int empid, double hourlyRate, double hoursWorked);
// constructor
void read_data_from_file();
double calculate_wage();
void print_data();
/* ASETTERS AND GETTERS */
void set_name (string n);
string get_name();
void set_id (int empid);
int get_id();
void set_rate (double hourlyRate);
double get_rate();
void set_hoursWorked(double hoursWorked);
double get_hoursWorked();
/* END OF SETTERS AND GETTERS */
};
This is my cpp
#include "Record.h"
Record::Record():name(), id(0), rate(0), hours(0) {} //default constructor
must be implemented first
Record::Record(string n, int empid, double hourlyRate, double hoursWorked)
{
name = n;
empid = id;
hourlyRate = rate;
hoursWorked = hours;
}
//
void Record::set_name(string n)
{
name = n;
}
string Record::get_name()
{
return name;
}
//
void Record::set_id(int empid)
{
id = empid;
}
int Record::get_id()
{
return id;
}
//
void Record::set_rate(double hourlyRate)
{
rate = hourlyRate;
}
double Record::get_rate()
{
return rate;
}
//
void Record::set_hoursWorked(double hoursWorked)
{
hours = hoursWorked;
}
double Record::get_hoursWorked()
{
return hours;
}
//
double Record::calculate_wage()
{
return (rate * hours);
}
There are some issues with your code that I can see. most of your problems aren't related to your question (I mean using a class or private/public members). you have more basic misunderstandings. So here's some explanation that might help you:
1- Using functions : You have some troubles using your defined functions, A function can have multiple input parameters and one return value. basically it's like this return_type function_name(parameter_type param1, ...). it means that if you call this function you need to pass param1,... and expect your function operation and then have a return value of return_type. You defined some set and get functions. if you want to set something you should call set function and pass your desired value to it and it will copy your value to your defined member data, after that you can call get function to retrieve that value. So when you call get function with parameter it will raise error. Here you want to call set function.
2- Using stoi : As you can see you are getting error on using stoi function too, this is a function for converting string to integer, The thing that you missed here is that this function declared in std namespace. If you want to use it you need to use it like this std::stoi(str). one other thing, using namespace std is a bad practice.
3- Design matters : In OOP design, a class must have a purpose and an actual job to do. It might be an interface to abstract class but a bunch of set and get functions will not fulfill the need to create a class. Here if your class is going to do file operations, it's OK, but as far as you shared your code it's just some set and get functions.

Request for Member in ' ' whitch is a non-class type

I want to create a object array of Accounts so I can manage them load everything from a file (by struct).
Im pretty new leaning c++ but I have no idea what I am doing wrong.
What does: Account** accounts[50] ?
"" accounts[i] = new Account*;
"" accounts[i]->newAccount(i, id_string, pw_string, level_int);
ERROR MESSAGE: request for member 'newAccount' in '* accounts[i]', which is of non-class type 'Account*'
AccountManagerFrm.cpp // Mainfile to run everything
#include "AccountManagerFrm.h"
#include "Account.h"
#include "ladeAccounts.h"
using namespace std;
Account** accounts [50];
void AccountManagerFrm::createAccountClick(wxCommandEvent& event)
{
accounts[i] = new Account*;
accounts[i]->newAccount(i, id_string, pw_string, level_int); // ERROR LINE
}
Account.cpp
class Account
{
struct iAccount
{
string ID;
string password;
int level;
};
Account()
{
}
void newAccount(int anzahl, string username, string pw, int lvl)
{
iAccount neu;
neu.ID = username;
neu.password = pw;
neu.level = lvl;
}
};
Account.h
#include <string>
using namespace std;
class Account{
public:
Account();
void newAccount(int anzahl, string username, string pw, int lvl);
void getInformationFromFile();
};
I want to create a object array of Accounts
That's just
Account accounts[50];
not your weird array of pointers to pointers. Then you can access one with .
accounts[i].newAccount(i, id_string, pw_string, level_int);
You'll also need to fix up the class definition. The definition itself, in the header, needs to contain all members. Also, the header should have a guard, to avoid errors if you include the header more than once. It's a bad idea to dump namespace std; into the global namespace; this pollutes the global namespace for everyone who includes the header. The whole header should be something like
#ifndef ACCOUNT_H
#define ACCOUNT_H
#include <string>
class Account {
public:
Account();
void newAccount(int anzahl, std::string username, string std::pw, int lvl);
void getInformationFromFile();
private:
std::string ID;
std::string password;
int level;
};
#endif
The source file should just define the member functions, not redefine the whole class:
#include "Account.h"
Account::Account() {}
void Account::newAccount(int anzahl, std::string username, std::string pw, int lvl)
{
ID = username;
password = pw;
level = lvl;
}
If you're struggling with basic class definitions, then you really should read a good introductory book. This is a complicated language, and you'll never learn it by guessing the syntax.

C++ Cannot use push_back on list containing custom structs

We are making a list that hold info on boardgames (name, year, score). We scan the info out of a .csv file, make a struct based on that info and then add the struct to a list. We keep doing this untill the document is done reading. Problem is that the push_back method of the list doesn't work. Here's the header of the list class:
NOTE BoardGame is the custom struct. BoardGame(wstring name, int year, float score).
#pragma once
#include "GameEngine.h"
#include "BoardGame.h"
#include <list>
class BoardGameList
{
public:
BoardGameList() {}
virtual ~BoardGameList() {}
// Methods
void Load(const tstring& fileName);
// Members
private:
std::list<BoardGame> m_Games;
};
The cpp file. Maybe I made the list the wrong way?
#include "BoardGameList.h"
#include <fstream>
void BoardGameList::Load(const tstring& fileName)
{
tifstream file(fileName);
tstring line;
if(!file)
{
GAME_ENGINE->MessageBox(_T("Error: The file could not be found!"));
}
else
{
tstring name;
tstring year;
tstring score;
while(!(file.eof()))
{
getline(file,line);
year = line.substr(0,4);
score = line.substr(5,5);
name = line.substr(11,line.find(_T("\n")));
float numberScore = std::stof(score);
int numberYear = std::stoi(year);
m_Games.push_back(BoardGame(name,numberYear,numberScore));
}
}
}
Running the program triggers an error (unhandled exception) that leads me to the following code in the "list" class itself I think.
_Unchecked_iterator _Unchecked_end()
{ // return unchecked iterator for end of mutable sequence
return (_Unchecked_iterator(this->_Myhead, this));
}
Any ideas why I can't add stuff to my list? I tried adding something in the constructor to check if it maybe needed an element before I could add more but even then, using a breakpoint showed me that the memory could not be read.
Many thanks in advance.
EDIT: Header of BoardGame
#pragma once
#include "GameEngine.h"
struct BoardGame
{
BoardGame(tstring name, int year, float score);
//Methods
tstring operator<<(BoardGame rhs);
//Members
tstring m_Name;
int m_Year;
float m_Score;
};
What exception is being thrown? This is vital to debugging your problem.
Without that information my best guess is this line:
name = line.substr(11,line.find(_T("\n")));
Will throw an exception on any line without a trailing newline, or any line less than 11 characters long.

What's wrong with this? Setters/Getters (edited ) header files included

when I have the following member in a class
employee headOfDepartment;
what's wrong these setters and getters?
void department::setHeadOfDepartment( employee depEmployee)
{
headOfDepartment=depEmployee;
}
employee department::getHeadOfDepartment()
{
return headOfDepartment;
}
I've been trying forever to define setters & getters with composition and it keeps getting me this error: "field ‘headOfDepartment’ has incomplete type"
ok Those are the header files:
#ifndef EMPLOYEE_H_
#define EMPLOYEE_H_
using namespace std;
#include <iostream>
#include <vector>
#include "department.h"
#include "project.h"
class department;
class project;
//#include <vector>
employee.h
class employee
{
string Name; //text with spaces
string National_ID; //unique value (text) for each employee
static double Salary; // value of 1500 pounds
char Gender; //character holds f or m
int Available_vacations; //initially starts with 15 days
static double Deduction_per_day; // value of 85.5 pounds
int Available_permission_hours; //initially starts with 20 hours
static double Deduction_per_hour; // value of 15.5 pounds
double Actual_salary; // value with actual salary after deductions
int Vacations; // vacations employee took
int Permessions; // permession hours employee took
int empSerialNum; // object order in vector
department* myDepartment;
vector < project > empProjects;
public:
employee (); // default constructor
employee (string myName, string myNationalID, char myGender,int mySerialNum); // Parameterized constructor
~employee(); // Destractor
//Setters
void setName(string myName);
void setNationalID (string myNationalID);
void setGender (char myGander);
void setAvailableVacation(int myAvVac);
void setAvailablepermissionhours (int myAvPerHours);
void setActualSalary (double actualSalary);
void setVacations(int myVacations);
void setPermessions(int myPermessions);
void setempSerialNum(int mySerialNum);
void setDepartment(department*);
void addProject(project);
//Getters
string getName();
string getNationalID ();
char getGender ();
int getAvailableVacation();
int getAvailablepermissionhours ();
double getActualSalary ();
int getVacations ();
int getPermessions ();
int getempSerialNum();
department* getDepartment();
project* getProjects();
void view (); // View to view Name, ID and actual salary
void View_Detailed (); //call previous function and also shows other details (vacations - permissions - detailed deductions - ... )
void Free_All(); //return all values to default
double Take_vacation(); //this function takes number of days employee need to take as vacation, available vacations reduced by number of days given, if available vacations became 0 salary is deduced by deduction per day set
double Take_permession(); //this function takes hours that employee asked to take, reduce available permission hour by hours given, if available permission become 0 hour salary is reduced by deduction per ho
double Calculate_Actual_Salary();// calculates salary after deductions and returns it
};
#endif
department.h
#ifndef DEPARTMENT_H_
#define DEPARTMENT_H_
using namespace std;
#include <string.h>
#include "employee.h"
#include "project.h"
#include <vector>
class project;
class employee;
class department{
private:
string name;
string ID;
employee headOfDepartment;
vector <project> depprojects; //projects managed by the department
public:
//constructors
department();
department(string, string);
//Setters
void setName(string);
void setID(string);
void setHeadOfDepartment( employee /*const&*/ depEmployee);
void addProject(project);
//Getters
string getName();
string getID();
employee getHeadOfDepartment() /*const*/;
// project getProjects();
};
#endif
project.h
#ifndef PROJECT_H_
#define PROJECT_H_
#include <string.h>
#include "department.h"
#include "project.h"
class department;
class project{
string name;
department* location;
public:
//constructors
project();
project(string proName, department* proDepartment);
//Setters
void setName(string proName);
void setLocation(department* proDepartment);
//Getters
string getName();
department* getLocation();
};
#endif
You need to the include the header file where employee is declared in your header and source files for department
Class employee shall be defined before using it as a type name of an object. Also I advice to add qualifier const for the getter
You are not including the header that defines employee in your department class header, but you have a non-reference non-pointer declaration of type employee in your header.

error LNK1169: one or more multiply defined symbols found

I have 3 files:
SilverLines.h
SilverLines.cpp
main.cpp
At SilverLines.cpp I have:
#include "SilverLines.h."
When I don't do:
#include "SilverLines.h"
at the main.cpp, everything is just fine. The project compiles.
But when I do:
#include "SilverLines.h"
in the main.cpp (Which i need to do), i get these 2 errors:
What's the problem?
> edit:
As you requested, this is the entire *.h code:
#ifndef SILVER_H
#define SILVER_H
#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>
#include <string>
#include <map>
using namespace std;
typedef unsigned short int u_s_int;
map<string /*phone*/,string /*company*/> companies; // a map of a phone number and its company
string findCompany(const string& phoneNum); //Given a phone number, the function returns the right company
//The Abstract Client Class:
class AbsClient //Abstract Client Class
{
protected:
//string phone_number;
int counter; //CALL DURATION TO BE CHARGED
double charge;
public:
string phone_number; //MOVE TO PROTECTED LATER
void setCharge(double ch) {charge=ch;}
void setCoutner(int count) {counter=count;}
AbsClient(string ph_num): phone_number(ph_num),counter(0), charge(0.0) {} //c'tor that must be given a phone#.
//Initializes the counter and the charge to 0.
virtual void registerCall(string /*phone#*/, int /*minutes*/) = 0; //make a call and charge the customer
void printReport(string /*phone#*/) const; //prints a minutes report
};
//The Temporary Client Class:
class TempClient : public AbsClient //TempClient class (NO DISCOUNT!) 2.3 NIS PER MINUTE, inherits from ABS
{
private:
string company;
public:
//string company;
TempClient(string ph_num, string cmp_name): AbsClient(ph_num), company(cmp_name) {}
virtual void registerCall(string /*phone#*/, int /*minutes*/); //make a call and charge the customer
//virtual void printReport(string phone) const {cout << "the number of minutes: " << this->counter << endl;}
};
//The REgistered Client Class:
class RegisteredClient : public AbsClient //RegisteredClient, 10% DISCOUNT! , inherits from ABS
{
protected:
string name;
string id;
long account; //ACCOUNT NUMBER
private:
static const int discount = 10; //STATIC DISCOUNT OF 10% FOR ALL Registered Clients
public:
RegisteredClient(string ph_num, string n, string i, long acc_num): AbsClient(ph_num), name(n) , id(i) , account(acc_num) {}
virtual void registerCall(string /*phone#*/, int /*minutes*/); //make a call and charge the customer
//virtual void printReport(string /*phone#*/) const {cout << "the number of minutes: " << this->counter << endl;}
};
//The VIP Client Class
class VIPClient : public RegisteredClient //VIP Client! X% DISCOUNT! also, inherits from RegisteredClient
{
private: //protected?
int discount; //A SPECIAL INDIVIDUAL DISCOUTN FOR VIP Clients
public:
VIPClient(string ph_num, string n, string i, long acc_num, int X): RegisteredClient(ph_num,n,i,acc_num), discount(X) {}
virtual void registerCall(string /*phone#*/, int /*minutes*/); //make a call and charge the customer
//virtual void printReport(string /*phone#*/) const {cout << "the number of minutes: " << this->counter << endl;}
};
//The SilverLines (the company) class
class SilverLines // The Company Class
{
protected:
vector<AbsClient*> clients;
vector<string> address_book; //DELETE
public:
//static vector<AbsClient*> clients;
//SilverLines();
void addNewClient(string /*phone#*/);
void addNewClient(string /*phone#*/, string /*name*/ , string /*id*/ , u_s_int /*importance lvl*/ , long /*account#*/);
void registerCall(string /*phone#*/ , int /*call duration*/);
void resetCustomer(string /*phone#*/); //given a phone#, clear the appropriate customer's data ('charge' and 'counter')
void printReport(string /*phone#*/) const;
~SilverLines(){
vector<AbsClient*>::iterator it;
for(it = clients.begin(); it != clients.end(); ++it)
delete(*it);
}
};
#endif
paercebal's Answer:
Your code has multiple issues (the
using namespace std;
for one), but the one failing the compilation is the declaration of a global variable in a header:
map<string /*phone*/,string /*company*/> companies;
I'm quite sure most of your sources (main.cpp and SilverLines.cpp, at least) include this header.
You should define your global object in one source file:
// SilverLines.h
extern map<string /*phone*/,string /*company*/> companies;
and then declare it (as extern) in the header:
// global.cpp
extern map<string /*phone*/,string /*company*/> companies;
Chances are that your "SilverLines.h" actually DOES define something, instead of just declaring it. I'm not going to try and decipher the error message, though :-)
Seems there are some multiple definitions coming due to inclusion of the SilverLines.h twice.
Pl. use a header guard like below in your SilverLines.h header file and then incude it.
This may help.
#ifndef SILVER_H
#define SILVER_H
//Write the contents of SilverLines.h here.
#endif // SILVER_H
You may have another error in your code.
ALso make sure that you are not writing your main or any other piece of code in .h file.
.h file should just contain the prototypes of the functions followed by a semi colon.
Thank you guys I worked it out:
findCompany() is now a global function, and map<string,string> companies is a static field inside it. It compiles great.