Homework Six
A Class for a File of Records

The purpose of this assignment is gain some experience writing a class to handle a file of records.

I have written some of the class. Most importantly, I wrote
-- the class declaration
-- main(), which drives the class
Your job is to finish writing these methods:
-- Add
-- Remove
-- Sort

To keep my job of grading manageable, will keep all the class components and main in a single file. Of course, normally we would use three files.

I do not think you will need to change my code.

Be sure to test your code!!!   Make sure you can print-all, delete, add, delete, sort, then print-all.

Email your single source code file to dannellys by 2:00pm on Tuesday April 5.



/************************************************************

A C++ Class to handle the file of faculty office records.

Steve Dannelly
March 2011
************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;


/***************************************************************************/
/***************************************************************************/
class FacultyOfficeClass
  {
   public:
      FacultyOfficeClass(char *filename);
      int Find_by_LName (char *LName);
      int Retrieve (int RRN, char *LName, char *FName, int &phone,int &office, char *dept);
      int Set (int RRN, char *LName, char *FName, int phone,int office, char *dept);
      void Print (int RRN);
      void PrintAll ();
      void Sort ();
      void Add (char *LName, char *FName, int phone,int office, char *dept);
      void Remove (int RRN);
   private:
      fstream myfile;                        // input AND output file
      int Num_Recs;                          // number of records in the file
      struct faculty_struct                  // the file's record structure
        {
         char fname[15],lname[15];
         int phone, office;
         char dept[5];
        };
  };
/***************************************************************************/
/***************************************************************************/


FacultyOfficeClass::FacultyOfficeClass (char *filename)
{
   /**** open the file ****/
   myfile.open (filename, ios::in | ios::out);
   if (!myfile)
     {
      cerr << "Error opening input file:" << filename << endl;
      exit (1);
     }

   /**** read the number of records *****/
   myfile.seekg (0, ios::beg);
   myfile.read(reinterpret_cast<char *> (&Num_Recs), sizeof(int));
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

int FacultyOfficeClass::Find_by_LName (char *LName)
{
   int i;
   struct faculty_struct next_rec;

   /**** skip the starting int ****/
   myfile.seekg (sizeof(int), ios::beg);

   /**** look at each record ****/
   for (i=0; i<Num_Recs; i++)
     {
      myfile.read(reinterpret_cast<char *> (&next_rec), sizeof(struct faculty_struct));
      if (strcmp(LName, next_rec.lname) == 0) // is this it????
      return i;
     }

   /**** if not found, return -1 ****/
   return -1;
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

int FacultyOfficeClass::Retrieve (int RRN,char *LName, char *FName,
                                  int &phone,int &office,char *dept)
{
   int byte_location;
   struct faculty_struct next_rec;

   /**** check for valid RRN ****/
   if (RRN < 0 || RRN > Num_Recs-1)
   return -1;

   /**** go get the right record ****/
   byte_location = sizeof(int) + (RRN * sizeof(struct faculty_struct));
   myfile.seekg (byte_location, ios::beg);
   myfile.read(reinterpret_cast<char *> (&next_rec), sizeof(struct faculty_struct));

   /**** set all the parameters ****/
   strcpy (LName, next_rec.lname);
   strcpy (FName, next_rec.fname);
   phone = next_rec.phone;
   office = next_rec.office;
   strcpy (dept, next_rec.dept);

   /**** return success ****/
   return 1;
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

int FacultyOfficeClass::Set (int RRN,char *LName, char *FName,
                             int phone,int office,char *dept)
{
   int byte_location;
   struct faculty_struct new_rec;

   /**** check for valid RRN ****/
   if (RRN < 0 || RRN > Num_Recs-1)
      return -1;

   /**** set all the fields ****/
   strcpy (new_rec.lname, LName);
   strcpy (new_rec.fname, FName);
   new_rec.phone = phone;
   new_rec.office = office;
   strcpy (new_rec.dept, dept);

   /**** go get the right record ****/
   byte_location = sizeof(int) + (RRN * sizeof(struct faculty_struct));
   myfile.seekp (byte_location, ios::beg);
   myfile.write(reinterpret_cast<char *> (&new_rec), sizeof(struct faculty_struct));

   /**** return success ****/
   return 1;
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

void FacultyOfficeClass::Print (int RRN)
{
   int byte_location;
   struct faculty_struct next_rec;

   /**** check for valid RRN ****/
   if (RRN < 0 || RRN > Num_Recs-1)
      return;
   
   /**** go get the right record ****/
   byte_location = sizeof(int) + (RRN * sizeof(struct faculty_struct));
   myfile.seekg (byte_location, ios::beg);
   myfile.read(reinterpret_cast<char *> (&next_rec), sizeof(struct faculty_struct));

   /**** print the record ****/
   cout << next_rec.fname << " " << next_rec.lname << endl;
   cout << "Thurmond " << next_rec.office << "     ext:" << next_rec.phone << endl;
   cout << next_rec.dept << " Dept\n";
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

void FacultyOfficeClass::PrintAll ()
{
   int i;

   /**** skip the starting int ****/
   myfile.seekg (sizeof(int), ios::beg);

   /**** print each record ****/
   for (i=0; i<Num_Recs; i++)
     {
      cout << "-------------------------------------\n";
      Print (i);
     }
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

void FacultyOfficeClass::Sort ()
{
   cout << "This should sort\n";
}


/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

void FacultyOfficeClass::Add (char *LName,char *FName,int phone,int office,char *dept)
{
   cout << "This should add\n";
}


/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

void FacultyOfficeClass::Remove (int RRN)
{
   cout << "This should remove\n";
}


/*******************************************************************************/
/*******************************************************************************/
/*******************************************************************************/

int main ()
{
   FacultyOfficeClass offices("faculty_sorted.dat");

   int RecNum;                                  // ID of the record to process
   char firstname[15], lastname[15], dept[5];   // temp fields
   int phonenumber, officenumber;               // temp fields
   char confirm[4];                             // really delete?
   int choice;                                  // user's menu choice

   do
     {
      /***** Get the User's Menu Choice *****/
      cout << "\n\nMenu:\n   1 - Find Someone\n   2 - Change Name\n";
      cout << "   3 - Change Office and Phone\n   4 - Add Entry\n";
      cout << "   5 - Delete Entry\n   6 - Re-Sort List\n";
      cout << "   7 - Print All\n   9 - Exit\n";
      cout << "Option? : ";
      cin >> choice;

      /***** Process the User's Request *****/
      switch (choice)
        {
         /******************* 1 - FIND SOMEONE *************************/
         case 1 : cout << "Last Name: ";                     // prompt user
                  cin >> lastname;
                  RecNum = offices.Find_by_LName (lastname); // find record
                  if (RecNum == -1)
                    {
                     cout << "========================\n";
                     cout << "       Not Found\n";
                     cout << "========================\n";
                    }
                  else                                       // print record
                    {
                     cout << "========================\n";
                     offices.Print (RecNum);
                     cout << "========================\n";
                    }
                  break;

         /******************* 2 - CHANGE NAME *************************/
         case 2 : cout << "Current Last Name: ";                // prompt user
                  cin >> lastname;
                  RecNum = offices.Find_by_LName (lastname);    // find record
                  if (RecNum == -1)
                    {
                     cout << "========================\n";
                     cout << "        Not Found\n";
                     cout << "========================\n";
                     break;
                    }
                  else                                          // update record
                    {
                     offices.Retrieve (RecNum,lastname,firstname,phonenumber,officenumber,dept);
                     cout << "New Last Name: ";
                     cin >> lastname;
                     cout << "New First Name: ";
                     cin >> firstname;
                     offices.Set (RecNum,lastname,firstname,phonenumber,officenumber,dept);
                    }
                  break;

         /******************* 3 - CHANGE OFFICE AND PHONE *************/
         case 3 : cout << "Last Name: ";
                  cin >> lastname;
                  RecNum = offices.Find_by_LName (lastname);
                  if (RecNum == -1)
                    {
                     cout << "========================\n";
                     cout << "      Not Found\n";
                     cout << "========================\n";
                     break;
                    }
                  else
                    {
                     offices.Retrieve (RecNum,lastname,firstname,phonenumber,officenumber,dept);
                     cout << "New Office Number: ";
                     cin >> officenumber;
                     cout << "New Phone Extension: ";
                     cin >> phonenumber;
                     offices.Set (RecNum,lastname,firstname,phonenumber,officenumber,dept);
                    }
                  break;

         /******************* 4 - ADD ENTRY ***************************/
         case 4 : cout << "New Last Name: ";           // read in each field
                  cin >> lastname;
                  cout << "New First Name: ";
                  cin >> firstname;
                  cout << "Office Number: ";
                  cin >> officenumber;
                  cout << "Phone Extension:";
                  cin >> phonenumber;
                  cout << "Department: ";
                  cin >> dept;                         // add new record
                  offices.Add (lastname,firstname,phonenumber,officenumber,dept);
                  break;
                  
         /******************* 5 - DELETE ENTRY *************************/
         case 5 : cout << "Last Name: ";                       // prompt user
                  cin >> lastname;
                  RecNum = offices.Find_by_LName (lastname);   // find record
                  if (RecNum == -1)
                     cout << "Entry Not Found\n";
                  else
                    {
                     offices.Retrieve (RecNum,lastname,firstname,phonenumber,officenumber,dept);
                     cout << "Really Delete the entry for ";   // confirm deletion
                     cout << firstname << " " << lastname << " (Yes/No) ? ";
                     cin >> confirm;
                     if (strcmp(confirm,"Yes")==0)
                       {
                        offices.Remove (RecNum);
                        cout << "Entry Deleted\n";
                       }
                     else
                        cout << "Entry Not Deleted\n";
                    }
                  break;

         /******************* 6 - RE-SORT LIST *************************/
         case 6 : offices.Sort();
                  break;

         /******************** 7 - PRINT ALL ***************************/
         case 7 : offices.PrintAll();
                  break;

         /******************* 9 - EXIT PROGRAM *************************/
         case 9 : break;

         /******************* NONE OF THE ABOVE ************************/
         default : cout << "Unknown Option\n";

         }                                // end of switch
     } while (choice != 9);
}