In-Class Exercise
File Operators
This exercise introduces member functions for reading from
and writing to a file, which enables client programs to backup
and restore object data.
Given Information
The following code is a solution to the Handout on
Custom I/O Operators.
Client Module
// Custom I/O Operators
// h10.cpp
#include <iostream>
#include "Employee.h"
int main() {
Employee mark, rose;
std::cin >> mark;
std::cin >> rose;
std::cout << mark << std::endl;
mark = mark + 0.50; // raise of 50 cents
std::cout << mark << std::endl;
std::cout << rose << std::endl;
rose = 0.50 + rose; // raise of 50 cents
std::cout << rose << std::endl;
}
|
Employee Module
Employee.h
// Custom I/O Operators
// Employee.h
#include <iostream>
const double MIN_WAGE = 10.25;
const int MAX_NAME = 20;
class Employee {
int no;
char name[MAX_NAME + 1];
double rate;
public:
Employee();
Employee(int, const char*);
Employee(int, const char*, double);
void display(std::ostream&) const;
Employee& operator+=(double);
};
Employee operator+(const Employee&, double);
Employee operator+(double, const Employee&);
std::istream& operator>>(std::istream&, Employee&);
std::ostream& operator<<(std::ostream&, const Employee&);
|
Employee.cpp
// Custom I/O Operators
// Employee.cpp
#include <iostream>
#include <iomanip>
#include <cstring>
#include "Employee.h"
Employee::Employee() {
// safe empty state
no = 0;
name[0] = '\0';
rate = MIN_WAGE;
}
Employee::Employee(int n, const char* nm) {
Employee temp(n, nm, MIN_WAGE);
*this = temp;
}
Employee::Employee(int n, const char* nm, double r) {
if (n > 0 && nm[0] != '\0' && r >= MIN_WAGE) {
no = n;
std::strncpy(name, nm, MAX_NAME); // copy first MAX_NAME characters
name[MAX_NAME] = '\0'; // ensure that last byte is null
rate = r;
} else {
Employee temp;
*this = temp;
}
}
void Employee::display(std::ostream& os) const {
if (no > 0) {
os << std::fixed << std::setprecision(2);
os << name << " (" << no << ") $" << rate;
}
else
os << "no data available";
}
Employee& Employee::operator+=(double r) {
if (no > 0 && r > 0.0)
rate += r;
return *this;
}
Employee operator+(const Employee& e, double r) {
Employee ee = e;
ee += r;
return ee;
}
Employee operator+(double r, const Employee& e) {
return e + r;
}
std::istream& operator>>(std::istream& is, Employee& e) {
int no;
char name[MAX_NAME + 1];
double rate;
std::cout << "Employee number : ";
is >> no;
is.ignore();
std::cout << "Employee name : ";
is.getline(name, MAX_NAME + 1);
std::cout << "Hourly Pay Rate : ";
is >> rate;
Employee temp(no, name, rate);
e = temp;
return is;
}
std::ostream& operator<<(std::ostream& os, const Employee& e) {
e.display(os);
return os;
}
|
Your Task
Add two member functions to the definition of the
Employee class for backing up and
restoring data. You may assume that any name in the
file contains no more than MAX_NAME
characters.
Client Module
The following main program uses your upgraded Employee class is
// Custom File Operators
// h11.cpp
#include <iostream>
#include <fstream>
#include "Employee.h"
int main() {
Employee mark, rose;
std::ofstream file("Employee.dat");
std::cin >> mark;
std::cin >> rose;
mark.save(file);
rose.save(file);
mark = mark + 0.50;
rose = rose + 0.75;
std::cout << mark << std::endl;
std::cout << rose << std::endl;
file.close();
std::ifstream oldData("Employee.dat");
mark.restore(oldData);
rose.restore(oldData);
std::cout << mark << std::endl;
std::cout << rose << std::endl;
}
|
Employee number : 3456
Employee name : Mark J.
Hourly Pay Rate : 10.25
Employee number : 3457
Employee name : Rose
Hourly Pay Rate : 10.70
Mark J. (3456) $10.75
Rose (3457) $11.20
Mark J. (3456) $10.25
Rose (3457) $10.70
|
Note that the name of an employee may contain whitespace.
Employee Module
Employee.h
Add the following to the header file for your upgraded class:
- include the fstream header file
- add the prototype for the save(std::ofstream&) member function that saves data to a file object
- add the prototype for the restore(std::ifstream) member function that restores data from a file object
// File Operators
// Employee.h
#include <iostream>
const double MIN_WAGE = 10.25;
const int MAX_NAME = 20;
class Employee {
int no;
char name[MAX_NAME + 1];
double rate;
public:
Employee();
Employee(int, const char*);
Employee(int, const char*, double);
void display(std::ostream&) const;
Employee& operator+=(double);
};
Employee operator+(const Employee&, double);
Employee operator+(double, const Employee&);
std::istream& operator>>(std::istream&, Employee&);
std::ostream& operator<<(std::ostream&, const Employee&);
|
Employee.cpp
Add the definitions for the save()
and restore() functions to the implementation file.
To accept input with embedded whitespace inside your definition of the overloaded
extraction operator, you need to use the get()
or getline() methods on the file input object.
// File Operators
// Employee.cpp
#include <iomanip>
#include <cstring>
#include "Employee.h"
Employee::Employee() {
// safe empty state
no = 0;
name[0] = '\0';
rate = MIN_WAGE;
}
Employee::Employee(int n, const char* nm) {
Employee temp(n, nm, MIN_WAGE);
*this = temp;
}
Employee::Employee(int n, const char* nm, double r) {
if (n > 0 && nm[0] != '\0' && r >= MIN_WAGE) {
no = n;
std::strncpy(name, nm, MAX_NAME); // copy first MAX_NAME characters
name[MAX_NAME] = '\0'; // ensure that last byte is null
rate = r;
} else {
Employee temp;
*this = temp;
}
}
void Employee::display(std::ostream& os) const {
if (no > 0) {
os << std::fixed << std::setprecision(2);
os << name << " (" << no << ") $" << rate;
}
else
os << "no data available";
}
Employee& Employee::operator+=(double r) {
if (no > 0 && r > 0.0)
rate += r;
return *this;
}
// save to file
//
// restore from file
//
Employee operator+(const Employee& e, double r) {
Employee ee = e;
ee += r;
return ee;
}
Employee operator+(double r, const Employee& e) {
return e + r;
}
std::istream& operator>>(std::istream& is, Employee& e) {
int no;
char name[MAX_NAME + 1];
double rate;
std::cout << "Employee number : ";
is >> no;
is.ignore();
std::cout << "Employee name : ";
is.getline(name, MAX_NAME + 1);
std::cout << "Hourly Pay Rate : ";
is >> rate;
Employee temp(no, name, rate);
e = temp;
return is;
}
std::ostream& operator<<(std::ostream& os, const Employee& e) {
e.display(os);
return os;
}
|
|
|
|