I'm making this program using a class named animal, below is the code:
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include "animal.h"
using namespace std;
int main() {
animal moke;
ofstream out;
out.open("/Users/Abel/Desktop/Cpp/animal/animal/animalRecords.txt");
vector<animal> monke;
bool quit = false;
while (!quit) {
int choice;
cout << "1. Add info for animals 2. Edit Info for animals 3. Exit\n";
cin >> choice;
string nam;
string spec;
int ag;
int editRow;
//menu
switch (choice) {
case 1:
cout << "Enter the Animal's name\n";
cin >> nam;
moke.setName(nam);
cout << "Enter the Species\n";
cin >> spec;
moke.setSpecies(spec);
cout << "Enter the age\n";
cin >> ag;
moke.setAge(ag);
monke.push_back(moke);
break;
case 2:
if(monke.size() == 0) {
cout << "Nothing to modify";
}
else {
for (int i = 0; i < monke.size(); i++) {
cout << i+1 << "\t\tName = " << monke[i].getName() << "\tSpecies = " << monke[i].getSpecies() << "\tAge = " << monke[i].getAge() << endl;
}
cout << "Which row would you like to edit\n";
cin >> editRow;
if (editRow > monke.size() || editRow < 1) {
cout << "Please follow directions\n";
}
else {
cout << "1. Edit name\t2. Edit species\t3. Edit age\n";
cin >> choice;
switch(choice) {
case 1:
cout << "Enter the new name\n";
cin >> nam;
monke[editRow-1].setName(nam);
break;
case 2:
cout << "Enter the new species\n";
cin >> spec;
monke[editRow-1].setSpecies(spec);
break;
case 3:
cout << "Enter the new age\n";
cin >> ag;
monke[editRow-1].setAge(ag);
break;
default:
cout << "You need to learn how to follow instruction <:(\n";
}
}
}
break;
case 3:
if (monke.size() == 0) {
cout << "Bye\n";
}
else {
for (int i = 0; i < monke.size(); i++)
out << i+1 << "\t\tName = " << monke[i].getName() << "\tSpecies = " << monke[i].getSpecies() << "\tAge = " << monke[i].getAge() << endl;
}
break;
default:
cout << "You are so basic\n";
break;
}
}
}
#pragma once
#include <string>
using namespace std;
class animal{
public:
animal();
animal(string name, string species, int age);
animal(animal &E);
void setName(string name);
void setSpecies(string species);
void setAge(int age);
string getName();
string getSpecies();
int getAge();
private:
string n, s;
int a;
};
#include "animal.h"
#include <string>
using namespace std;
animal::animal() {
n = "";
s = "";
a = 0;
}
animal::animal(string name, string species, int age) {
n = name;
s = species;
a = age;
}
animal::animal(animal &E) {
a = E.a;
s = E.s;
s = E.s;
}
void animal::setName(string name) {
n = name;
}
void animal::setSpecies(string species) {
s = species;
}
void animal::setAge(int age) {
a = age;
}
string animal::getName() {
return n;
}
string animal::getSpecies() {
return s;
}
int animal::getAge() {
return a;
}
When running this, it shows these errors:
No matching constructor for initialization of 'animal'
is_cpp17_move_insertable<std::allocator<animal>, void>::value' "The specified type does not meet the requirements of Cpp17MoveInsertable"
No matching constructor for initialization of 'animal'
Related
Recently I had to migrate one of my small turn-in projects from VS to CodeBlocks.
In VS the project worked and run just fine.
Now that I have moved my .cpp and .h to CB it runs to an error and I can't see why, because I am referring to the Menu.h.
Main:
#include <iostream>
#include "Menu.h"
#include "Bulk.h"
#include "Parcel.h"
#include <fstream>
using namespace std;
int main()
{
Menu m1 = Menu();
m1.Start();
}
Menu.cpp:
#include "Menu.h"
#include "Material.h"
#include "Bulk.h"
#include "Parcel.h"
#include <iostream>
#include <string>
#include <deque>
using namespace std;
deque<Parcel> Parcels;
deque<Bulk> Bulks;
void Menu::Start()
{
string selection = "F";
for (int i = 0; i < 1;)
{
cout << "*****Warehouse Manager*****\n";
cout << "1 - Add Material\n";
cout << "2 - List Materials\n";
cout << "3 - Add Stock\n";
cout << "4 - Decrease Stock\n";
cout << "E - Exit\n";
cin >> selection;
if (selection == "1")
{
AddMaterial();
}
if (selection == "3")
{
AddStock();
}
if (selection == "2")
{
PrintAll();
}
if (selection == "4")
{
RemoveStock();
}
if (selection == "E")
{
i++;
}
}
}
void Menu::RemoveStock()
{
string code;
double stock;
cout << "Please enter ID Code:\n";
cin >> code;
cout << "Please enter value:\n";
cin >> stock;
for (int i = 0; i < Parcels.size(); i++)
{
if (Parcels[i].GetEAN() == code)
{
Parcels[i].DecreaseStock(stock);
}
}
for (int i = 0; i < Bulks.size(); i++)
{
if (Bulks[i].GetIDCode() == code)
{
Bulks[i].DecreaseStock(stock);
}
}
}
void Menu::PrintAll()
{
for(int i = 0; i < Parcels.size(); i++)
{
Parcels[i].Print();
}
for (int i = 0; i < Bulks.size(); i++)
{
Bulks[i].Print();
}
}
void Menu::AddStock()
{
string code;
double stock;
cout << "Please enter ID Code:\n";
cin >> code;
cout << "Please enter value:\n";
cin >> stock;
for (int i = 0; i < Parcels.size(); i++)
{
if (Parcels[i].GetEAN() == code)
{
Parcels[i].IncreaseStock(stock);
}
}
for (int i = 0; i < Bulks.size(); i++)
{
if (Bulks[i].GetIDCode() == code)
{
Bulks[i].IncreaseStock(stock);
}
}
}
void Menu::AddMaterial()
{
string selection = "F";
cout << "Please choose:\n";
cout << "1 - Parcel\n";
cout << "2 - Bulk\n";
cin >> selection;
if(selection == "1")
{
string name;
string company;
string ean;
double pieceprice;
cout << "Please enter material name:\n";
cin >> name;
cout << "Please enter the company:\n";
cin >> company;
cout << "Please enter the EAN ID:\n";
cin >> ean;
cout << "Please enter the price:\n";
cin >> pieceprice;
Parcel p1 = Parcel(name, company, ean, pieceprice);
Parcels.push_front(p1);
}
if (selection == "2")
{
string name;
string company;
string idcode;
string unit;
double unitprice;
cout << "Please enter material name:\n";
cin >> name;
cout << "Please enter the company:\n";
cin >> company;
cout << "Please enter the ID:\n";
cin >> idcode;
cout << "Please enter the unit:\n";
cin >> unit;
cout << "Please enter price per 1 unit:\n";
cin >> unitprice;
Bulk b1 = Bulk(name,company,idcode,unit,unitprice);
Bulks.push_front(b1);
}
}
Menu.h:
#pragma once
#include "Material.h"
#include "Bulk.h"
#include "Parcel.h"
#include <iostream>
#include <string>
#include <deque>
using namespace std;
class Menu
{
public:
void Start();
void AddMaterial();
void AddStock();
void PrintAll();
void RemoveStock();
private:
};
The error is the following:
Do you guys have any idea what is going on? How come that it runs perfectly in VS but not in CB?
Thank you!
hi I write this following code after I debug when I try to read inside of my file after reading data when it returns from (printdata()) function i witness the following error can any one help me about this error?
Unhandled exception at 0x0F50DF58 : 0xC0000005: Access violation reading location 0x0047CA04.
////////////Library.h
#include <string>
using namespace std;
class Library
{
private:
string BookName;
string Author;
int Day,Month,Year ; //day month year
float Price;
string Subject;
double ISBN;
public:
Library(string = "", string = "", int = 0, int = 0, int = 0, float = 0.0, string = "", double = 0.0);
void setBookName(string);
void setAuthor(string);
void setPurchaseDay(int );
void setPurchaseMonth(int);
void setPurchaseYear(int);
void setPrice(float);
void setSubject(string);
void setISBN(double);
string getBookName();
string getAuthor();
int getPurchaseDay();
int getPurchaseMonth();
int getPurchaseYear();
float getPrice();
string getSubject();
double getISBN();
};
///////Linrary.cpp
#include "stdafx.h"
#include "Library.h"
#include <iostream>
#include <string>
using namespace std;
Library::Library(string bookname, string author,int day,int month,int year, float price, string subject, double isbn)
{
setBookName(bookname);
setAuthor(author);
setPurchaseDay(day);
setPurchaseMonth(month);
setPurchaseYear(year);
setPrice(price);
setSubject(subject);
setISBN(isbn);
}
void Library::setBookName(string bookname)
{
BookName = bookname;
}
void Library::setAuthor(string author)
{
Author = author;
}
void Library::setPurchaseDay( int day)
{
Day = day;
}
void Library::setPurchaseMonth(int month)
{
Month = month;
}
void Library::setPurchaseYear(int year)
{
Year = year;
}
void Library::setPrice(float price)
{
Price = price;
}
void Library::setSubject(string subject)
{
Subject = subject;
}
void Library::setISBN(double isbn)
{
ISBN = isbn;
}
///////////////////////////////////////////////
string Library::getBookName()
{
return BookName;
}
string Library::getAuthor()
{
return Author;
}
int Library::getPurchaseDay()
{
return Day;
}
int Library::getPurchaseMonth()
{
return Month;
}
int Library::getPurchaseYear()
{
return Year;
}
float Library::getPrice()
{
return Price;
}
string Library::getSubject()
{
return Subject;
}
double Library::getISBN()
{
return ISBN;
}
////////main function
#include "stdafx.h"
#include "Library.h"
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <cstdlib>
using namespace std;
int menu();
void EnterData();
void PrintData();
int main(int argc, char *arg[])
{
for (;;)
{
system("cls");
int c = menu();
switch (c)
{
case 1:
EnterData();
break;
case 2:
PrintData();
break;
case 8:
exit(0);
}//end of switch
}//end of for
}
int menu()
{
int p;
do
{
cout << "1. Enter Data of a Book." << endl;
cout << "2. Print Data of all Books." << endl;
cout << "3. Search a Book by Subject." << endl;
cout << "4. Search a Book by Auther." << endl;
cout << "5. Pirnt Books Purchased in a Period of Time." << endl;
cout << "6. Search by ISBN." << endl;
cout << "7. Price of Books Purchased in a Period of Time." << endl;
cin >> p;
} while (p < 0 || p>7);
cin.get();
return p;
}//end of menu() function
//***************Enter Data to File****************8
void EnterData()
{
system("cls");
ofstream fp("LIB.txt", ios::out | ios::trunc);
if (!fp)
{
cerr << "\nError in opening file to write in...";
cin.get();
exit(1);
}
Library data1;
cout << "\nEnter data of the book and write '.' instead of name to finilize."<<endl<<endl;
string bookname, author, subject;
int day, month, year;
float price;
double isbn;
do{
cout << "\nBook Name: ";
getline(cin, bookname);
data1.setBookName(bookname);
if (bookname == ".")
{
author = ".";
subject = ".";
price = 0.0;
isbn = 0;
day = month = year = 0;
data1.setAuthor(author);
data1.setSubject(subject);
data1.setPrice(price);
data1.setISBN(isbn);
data1.setPurchaseDay(day);
data1.setPurchaseMonth(month);
data1.setPurchaseYear(year);
fp.write((char*)(&data1), sizeof(Library));
return;
}
cout << "\nAuthor: ";
getline(cin, author);
data1.setAuthor(author);
cout << "\nPurchase Date (day,month,year): ";
cin >> day;
cin >> month;
cin >> year;
cin.ignore();
data1.setPurchaseDay(day);
data1.setPurchaseMonth(month);
data1.setPurchaseYear(year);
cout << "\nPrice: ";
cin >> price;
data1.setPrice(price);
cin.ignore();
cout << "\nSubject: ";
getline(cin, subject);
data1.setSubject(subject);
cout << "\nISBN: ";
cin >> isbn;
data1.setISBN(isbn);
cin.ignore();
fp.write((char*)(&data1), sizeof(Library));
} while (1);
fp.close();
cin.get();
}//enter of enterdata() function
//***************Print Data********************
void PrintData()
{
system("cls");
ifstream fp("LIB.txt", ios::in);
if (!fp)
{
cerr << "\nError in opening file to write in...";
cin.get();
exit(2);
}
Library data2;
string bookname, author, subject;
int day, month, year;
float price;
double isbn;
cout << left << setw(12) << "BookName" << setw(12) << "Author" << setw(12) << "PurchaseDate"
<< right<<setw(7) << "Price" << setw(12) << "Subject" << setw(7) << "ISBN"<<endl;
cout << "____________________________________________________________________"<<endl;
fp.read((char *)(&data2), sizeof(Library));
while ( fp && !fp.eof())
{
bookname=data2.getBookName();
author=data2.getAuthor();
day=data2.getPurchaseDay();
month = data2.getPurchaseMonth();
year = data2.getPurchaseYear();
price = data2.getPrice();
isbn = data2.getISBN();
subject = data2.getSubject();
//cout << left << setw(12) << bookname << setw(12) << author << setw(12) << purchasedate[0] << purchasedate[1] << purchasedate[2]
//<< right << setw(7) << price << setw(12) << subject << setw(7) << isbn << endl;
if (bookname.at(0) == '.')
{
fp.close();
break;
}
fp.read((char *)(&data2), sizeof(Library));
}
cin.get();
//fp.close();
//return;
}
disclaimer I am by no means a C programmer, and very well may be wrong here.
Your issues is probably coming from here:
fp.write((char*)(&data1), sizeof(Library));
You are passing the method data1, but telling it that the size of the file it should write is the size of Library, where it should be the size of data.
Library, being larger then data1, will cause a buffer overrun, where you will try reading a memory address outside of your application / variable.
I have wriiten a code to add , delete and dispaly a record of employees consisting of employee ID ,name,age and location.
But I am unable to code the delete function
My code is as follows:
#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
class Document
{
public:
int Add();
void Delete();
void Display();
int No_of_lines();
int empno();
private:
fstream document;
fstream newdocument;
string data;
int age;
int emp_id;
int idtodelete;
char name[100],loc[100];
};
int Document::No_of_lines()
{
int number = 0;
document.open("document.txt");
while (getline(document, data))
{
++number;
}
return number;
}
int Document::Add()
{
Document d1;
document.open ( "document.txt",ios::app);
int x = d1.No_of_lines();
int emp_id = ++x;
cout << "The employee ID is: " << emp_id;
document <<emp_id;
cout<< "\n Ënter Name:" ;
cin>>name;
document <<"\t Name:"<< name;
cout<<"Enter Age:";
cin>> age;
document << "\t Age:"<< age;
cout<< "Enter location:";
cin>> loc;
document << "\t Location:"<< loc;
document << "\n";
document.close();
return 0;
}
void Document::Delete()
{
Document d2;
d2.Display();
int num;
char line[1000];
document.open("document.txt");
newdocument.open("newdocument.txt");
cout << "Enter the ID to delete \n";
cin >> idtodelete;
while (document.good())
{
const int maxchar = 1000;
const int maxtokens = 10;
char* token[maxtokens] = {};
char split[maxchar];
document.getline(split, maxchar);
int n = 0;
token[0] = strtok(split, " ");
istringstream(token[0]) >> num;
if (num != idtodelete)
{
document >> emp_id >> name >> age >> loc;
newdocument << emp_id<< name<< age<< loc;
}
else
{
}
}
document.close();
newdocument.close();
remove("document.txt");
rename("newdocument.txt", "document.txt");
}
void Document::Display()
{
document.open("document.txt");
while (!document.eof())
{
getline(document,data);
cout<<data<<endl;
}
document.close();
}
int main()
{
Document d;
char ans;
int ch;
do
{
system ( "cls");
cout<< "Enter your choice \n";
cout << "\t1. Add Data \n " << "\t2. Delete Data \n" << "\t3. Display Data \n";
cout<< "\t4. Exit\n";
cout<< " Enter Choice \n ";
cin >> ch;
switch(ch)
{
case 1:
cout << " Adding Data : \n";
d.Add();
break;
case 2:
//cout << "Deleting data : \n";
d.Delete();
break;
case 3:
cout << "Displaying data : \n";
d.Display();
break;
case 4:
cout << "Exit";
break;
default :
cout << "Invalid Input \n";
break;
}
cout<< " click y to quit or any other key to continue " ;
cin>>ans;
}
while (ans != 'y');
return 0;
}
The simple way is to remove by employee ID. You just ask for the employee ID, to know what employee to remove.
Then, you cannot remove lines in the middle of a sequential file, so you just
rename the file as document.back
create a new document.txt
read document.back and copy all employees to document.txt except the one you want to delete
close both files
remove document.back
That's all ... except for the usual test for IO errors, backup file existing, and so on...
I tested your code. First, you forgot to close document in method int Document::No_of_lines(). Next on my MSVC2008, I have to explicitely call document.clear() after reaching end of file. You also do not test document immediately after a getline, meaning that you execute the code after a bad read.
I removed newdocument from Document class, because IMHO it is useless. Here is a possible implementation of Delete:
void Document::Delete()
{
Document d2;
Display();
int num;
document.open("document.txt");
document.clear();
d2.document.open("newdocument.txt", ios::out | ios::trunc);
cout << "Enter the ID to delete \n";
cin >> idtodelete;
while (document.good())
{
getline(document, data);
if (document) {
int n = 0;
istringstream(data) >> num;
if (num != idtodelete)
{
d2.document << data << endl;
}
}
}
document.close();
d2.document.close();
remove("document.txt");
rename("newdocument.txt", "document.txt");
}
I have been having some trouble on my code for my final project. I have looked everwhere and I am having a hard time so I thought I would ask on here. I need to make sure that when all the names are listed in this phonebook that they will come out in alphabetical order but as of yet I am unsure how to do that. Here is the program that i currently have! Thank you!
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
struct Contact {
string name, number, notes;
};
Contact contactList[100];
int rec_num = 0;
int num_entries;
string toUpper (string S) {
for (int i= 0; i < S.length(); i++)
S[i] = toupper(S[i]);
return S;
}
void ReadFile () {
string S;
fstream input("PhoneData.txt");
while (!input.eof() && !input.fail()){
input >> contactList[rec_num].name >> contactList[rec_num].number;
getline(input, S);
contactList[rec_num].notes = S;
rec_num++;
}
cout << "Book read." << endl;
num_entries = rec_num;
input.close();
return;
}
// stores phonebook for future runs of the program
void StoreFile () {
fstream F ("PhoneData.txt");
rec_num = 0;
while (rec_num < num_entries){
F << contactList[rec_num].name << " " << contactList[rec_num].number << " " << contactList[rec_num].notes << " " << endl;
rec_num++;
}
cout << "Phonebook stored." << endl;
return;
}
// adds contact
void add_name(string name, string number, string notes){
contactList[num_entries].name = name;
contactList[num_entries].number = number;
contactList[num_entries].notes = notes;
num_entries++;
return;
}
// finds contact
void retrieve_name(string name){
for (int i = 0; i < num_entries; i++){
if (toUpper(contactList[i].name) == toUpper(name)) {
cout << "Phone Number: " << contactList[i].number << endl << "Notes: " << contactList[i].notes << endl;
return;
}
}
cout << "Name not found" << endl;
return;
}
// updates contact info
void update_name(string name){
string new_number;
string new_notes;
cout<<"New Phone Number"<<endl;
cin>> new_number;
cout<<"New Notes"<<endl;
cin>> new_notes;
for (int i = 0; i < num_entries; i++){
if (toUpper(contactList[i].name) == toUpper(name)) {
contactList[i].number = new_number;
contactList[i].notes = new_notes;
return;
}
}
}
// deletes contact
void delete_name(string name){
int INDEX=0;
for (int i = 0; i < num_entries; i++){
if (toUpper(contactList[i].name) == toUpper(name)) {
INDEX=i;
for ( int j=INDEX; j < num_entries; j++ ){
contactList[j].name = contactList[j+1].name;
contactList[j].number = contactList[j+1].number;
contactList[j].notes = contactList[j+1].notes;
}
}
}
return;
}
void listAllContacts() {
int i = 0;
while (i < num_entries) {
cout << "-- " << contactList[i].name << " " << contactList[i].number << endl << "-- " << contactList[i].notes << endl << endl;
i++;
}
}
int main(){
string name, number, notes;
string FileName;
char command;
FileName = "PhoneData.txt";
ReadFile ();
cout << "Use \"e\" for enter, \"f\" for find, \"l\" for list, \"d\" for delete, \"u\" for update, \"s\" for send message, \"q\" to quit." << endl << "Command: ";
cin >> command;
while (command != 'q'){
switch (command){
case 'e': cin >> name; cout << "Enter Number: ";
cin >> number; cout << "Enter Notes: ";
cin.ignore(); getline(cin, notes);
add_name(name, number, notes); break;
case 'f': cin >> name; retrieve_name(name); break;
case 'l':
listAllContacts(); break;
case 'u': cin>> name; update_name (name);break;
case 'd' : cin>> name; delete_name (name); break;
}
cout << "\nCommand: "; cin >> command;
}
StoreFile();
cout << "All set !";
return 0;
}
Given
Contact contactList[100];
int num_entries;
you can use std::sort to sort the list of contacts. std::sort has two forms. In the first form, you can use:
std::sort(contanctList, contactList+num_entries);
if you define operator< for Contact objects.
In the second form, you can use:
std::sort(contanctList, contactList+num_entries, myCompare);
if you define myCompare to be callable object that can compare two Contact objects.
To use the first form, change Contact to:
struct Contact {
string name, number, notes;
bool operator<(Contact const& rhs) const
{
return (this->name < rhs.name);
}
};
If you want to the comparison of names to be case insensitive, convert both names to either uppercase or lowercase and them compare them.
I think I am having trouble with binary file io. If I run my program, create some employee objects and then display them everything works fine. If I save the object data and reload the program I get an RTTI exception. It apears to me that my LoadEmployeeData() and Savelist(vector &e) functions work just fine. The exception occurs in my DisplayEmployeeData() function when I try to use typeid.
Just to reiterate, I am getting an RTTI error when using typeid on an object loaded from disk.
//****************header file***********
#include <string.h>
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
#include <typeinfo>
#include <ctime>
#include <cstdlib>
using namespace std;
class Employee
{
private:
int employeeID;
char name[80];
int SSN;
public:
Employee();
Employee(int, char*,int);
virtual ~Employee();
virtual void DisplayBaseData();
//getters
int GetID();
char* getName();
int GetSSN();
//setters
void SetID(int);
void SetName(char*);
void SetSSN(int);
};//end Employee class
class Salary : public Employee
{
private:
double salary;
public:
Salary();
Salary(int, char*, int, double); //id, name, ssn, salary
~Salary();
void DisplayEmployeeData();
//getters
double GetSalary();
//setters
void SetSalary(double);
};//end class Exempt
class Hourly : public Employee
{
private:
double rate;
double hoursWorked;
public:
Hourly();
Hourly(int, char*, int, double, double); //id, name, ssn, rate
~Hourly();
void DisplayEmployeeData();
//getters
double GetRate();
double GetHoursWorked();
//setters
void SetRate(double);
void SetHoursWorked(double);
};//end Hourly Class
const int HOURLYTYPE = 0;
const int SALARYTYPE = 1;
//*******body*******
#include "lab05.h";
Employee::Employee(){};
Employee::Employee(int ID, char* nme, int ssn) : employeeID(ID), SSN(ssn)
{
strcpy(name, nme);
}
int Employee::GetID()
{
return employeeID;
}
char* Employee::getName()
{
return name;
}
int Employee::GetSSN()
{
return SSN;
}
void Employee::SetID(int i)
{
employeeID = i;
}
void Employee::SetName(char* n)
{
strcpy(name, n);
}
void Employee::SetSSN(int i)
{
SSN = i;
}
void Employee::DisplayBaseData()
{
cout << "ID: \t" << employeeID << endl;
cout << "Name: \t " << name << endl;
cout << "SSN: \t" << SSN << endl;
}
Employee::~Employee(){}
Salary::Salary(){}
Salary::Salary(int id, char* nme, int ssn, double slry) : Employee(id, nme, ssn), salary(slry){}
void Salary::DisplayEmployeeData()
{
DisplayBaseData();
cout << "Salary: \t " << salary << endl;
}
double Salary::GetSalary()
{
return salary;
}
void Salary::SetSalary(double d)
{
salary = d;
}
Salary::~Salary(){}
Hourly::Hourly(){}
Hourly::Hourly(int id, char* nme, int ssn, double rte, double worked) : Employee(id, nme, ssn), rate(rte), hoursWorked(worked){}
void Hourly::DisplayEmployeeData()
{
DisplayBaseData();
cout << "Rate: \t" << rate << endl;
cout << "Worked: \t " << hoursWorked << endl;
}
double Hourly::GetRate()
{
return rate;
}
double Hourly::GetHoursWorked()
{
return hoursWorked;
}
void Hourly::SetRate(double d)
{
rate = d;
}
void Hourly::SetHoursWorked(double d)
{
hoursWorked = d;
}
Hourly::~Hourly(){}
vector<Employee*> LoadEmployeeData()
{
vector<Employee*> employeeList;
string fileName = "";
cout << "\nEnter filename for employee data: ";
cin >> fileName;
fstream file;
file.open(fileName, ios::in, ios::binary);
char buffer[4096] = {0};
int numEntries;
file.read((char*)&numEntries, sizeof(int));
cout << numEntries << " number of entries found." << endl;
if (numEntries != 0)
{
int identifier;
for (int i = 0; i < numEntries; i++)
{
file.read((char*)&identifier, sizeof(int));
if (identifier == SALARYTYPE)
{
Employee* temp = new Salary();
file.read((char*)temp, sizeof(Salary));
employeeList.push_back(temp);
}
else if (identifier == HOURLYTYPE)
{
Employee* temp = new Hourly();
file.read((char*)temp, sizeof(Hourly));
employeeList.push_back(temp);
}
}
}
else cout << "No Entries found." << endl;
file.close();
return employeeList;
}//end LoadEmployeeData function
void ListEmployees(vector<Employee*> &e)
{
if (e.size() != 0)
{
for (int i = 0; i < e.size(); i++)
{
if (typeid(*(e[i])) == typeid(Hourly))
{
cout << "\n(" << i << ")" << endl;
dynamic_cast<Hourly*>(e[i])->DisplayEmployeeData();
}
else if (typeid(*(e[i])) == typeid(Salary))
{
cout << "\n(" << i << ")" << endl;
dynamic_cast<Salary*>(e[i])->DisplayEmployeeData();
}
}
}
else cout << "No items in list" << endl;
}// end ListEmployees function
void ModifyEmployee(vector<Employee*> &e)
{
cout << "Enter employee selection." << endl;
}
void CreateEmployee(vector<Employee*> &e)
{
bool continueLoop = true;
srand(time(0)); //seed random number generator
cout << "\n Enter new employee information." << endl;
cout << "Name: ";
char newName[80] = {0};
cin >> newName;
cout << "\n SSN: ";
int newSSN;
cin >> newSSN;
char newType = '-1';
do
{
cout << "\n Is new employee paid a (s)alary or (h)ourly rate? ";
cin >> newType;
if (newType == 's' || newType == 'h') continueLoop = false;
else cout << "incorrect input" << endl;
}while (continueLoop == true);
if (newType == 's')
{
cout << "Enter salary amount: ";
double amount;
cin >> amount;
e.push_back(new Salary(rand() % 1000 + 1, newName, newSSN, amount));
}
else if (newType == 'h')
{
cout << "Enter hourly amount: ";
double amount;
cin >> amount;
cout << "Enter hours worked: ";
double hoursWorked;
cin >> hoursWorked;
e.push_back(new Hourly(rand() % 1000 + 1, newName, newSSN, amount, hoursWorked));
}
}
void Savelist(vector<Employee*> &e)
{
if (e.size() == 0)
cout << "No employees in list. Nothing done." << endl;
else
{
cout << "Enter save filename: ";
char fileName[80] = {'\0'};
cin >> fileName;
fstream* file = new fstream();
file->open(fileName, ios::out, ios::binary);
char buffer[80] = {'\0'};
int numEntries = e.size();
file->write((char*)&numEntries, sizeof(int)); //writes number of entries
for (int i = 0; i < e.size(); i++)
{
if (typeid(*e[i]) == typeid(Salary))
{
int classType = SALARYTYPE;
file->write((char*)&classType, sizeof(int));
file->write((char*)dynamic_cast<Salary*>(e[i]), sizeof(Salary));
}
else if (typeid(*e[i]) == typeid(Hourly))
{
int classType = HOURLYTYPE;
file->write((char*)&classType, sizeof(int));
file->write((char*)dynamic_cast<Hourly*>(e[i]), sizeof(Salary));
}
}
file->close();
}
}
void DeleteEmployee(vector<Employee*> &e)
{
cout << "Input index number of employee to delete: ";
int idx = 0;
cin >> idx;
if (idx > e.size() -1)
cout << "invalid index number\n" << endl;
else
{
delete e[idx];
e.erase(e.begin() + idx); //removes from list
}
}
int main()
{
const int ZERO = 0;
const int ONE = 1;
const int TWO = 2;
const int THREE = 3;
const int FOUR = 4;
const int FIVE = 5;
const int SIX = 6;
int exitMainLoop = false; //for flow control
int mainMenuChoice = -1;
vector<Employee*> employeeList;
do
{
cout << "Select from the following options." << endl;
cout << "(1) Load employee data file." << endl;
cout << "(2) View Employees." << endl;
cout << "(3) Modify Employee data. " << endl;
cout << "(4) Create new employee." << endl;
cout << "(5) Save list to file." << endl;
cout << "(6) Delete employee data. " << endl;
cout << "(0) Exit program." << endl;
//add more options
cout << "Enter selection: ";
cin >> mainMenuChoice;
if (cin.fail())
{
cout << "\nInvalid selection. Try again" << endl;
cin.clear();
string garbage = "";
cin >> garbage;
}
else if (mainMenuChoice == ONE)
employeeList = LoadEmployeeData();
else if (mainMenuChoice == TWO)
ListEmployees(employeeList);
else if (mainMenuChoice == THREE)
ModifyEmployee(employeeList);
else if (mainMenuChoice == FOUR)
CreateEmployee(employeeList);
else if (mainMenuChoice == FIVE)
Savelist(employeeList);
else if (mainMenuChoice == SIX)
DeleteEmployee(employeeList);
else if (mainMenuChoice == ZERO)
exitMainLoop = true;
}while(exitMainLoop == false);
system("PAUSE");
}
You can't read/write raw C++ objects from/to disk if they have virtual methods (or use RTTI, which requires virtual methods) because there's no guarantee that the vtable address from the first execution will be written to disk, and there's no guarantee that the vtable will be in the same place the next time the program is run -- hence, the address that was written to disk will point somewhere incorrect when it is read back.
file->write((char*)dynamic_cast<Hourly*>(e[i]), sizeof(Salary));
looks suspicious. did you mean sizeof(Hourly)?