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






  Designed by Chris Szalwinski   Copying From This Site   
Logo
Creative Commons License