//------------------------------------------ // Proj3-4.C - advanced solution to project 3 // // Dennis L. Frey CMSC 202 Fall 2002 // // This program uses an advanced coding technique // known as a jump table. this table contains // the addresses of the functions to be called. // This eliminates the need for the switch statement // in Proj3-3.C // To use this technique, all functions must have // the same prototype, so the functions Books() // and Patrons() take an ifstream as a new parameter // even though they are not used. //------------------------------------------------- // // If a new command is added, just add the command // string to the array of commands, the name of // the function to the array of function pointers // and write the function // //---------------------------------------------- // With this many functions, it's probably a good idea // to create an auxiliary .C and .H file. //----------------------------------------------- #include #include #include #include "library.H" using namespace std; // function prototypes for functions // in this file. Note all command related // functions need the same prototype // to be used in the jump table void AddBook (ifstream& in, Library& lib); void AddPatron (ifstream& in, Library& lib); void Books (ifstream& in, Library& lib); void CheckIn (ifstream& in, Library& lib); void CheckOut (ifstream& in, Library& lib); void Patrons (ifstream& in, Library& lib); void PatronsBooks (ifstream& in, Library& lib); bool ReadLine (ifstream& in, string& s); // array of command strings // same order as const ints above const int NRCOMMANDS = 7; const string commands[NRCOMMANDS] = {"ADDBOOK", "ADDPATRON", "BOOKS", "PATRONS", "CHECKIN", "CHECKOUT", "PATRONSBOOKS" }; // an array of pointers to void functions // this array must be in the same order as the // the list of commands above void (*funcs[NRCOMMANDS])(ifstream& in, Library& lib) = { AddBook, AddPatron, Books, Patrons, CheckIn, CheckOut, PatronsBooks }; int main (int argc, char *argv[] ) { // check number of command line args if (argc != 2) { cerr << "Usage: Proj2 " << endl; exit (-1); } // instantiate and open the file ifstream infile (argv[1]); if (!infile) { cerr << "Unable to open file: " << argv[1] << endl; exit (-2); } // a-ok, instantiate library Library library; string command; // loop until no more commands while (ReadLine (infile, command)) { // switch to function for the command // 'while' uses short-circuit evaluation int i = 0; while ((i < NRCOMMANDS) && (commands[i] != command)) i++; if (i < NRCOMMANDS) // call function associated with the command (*funcs[i]) (infile, library); else cerr << "Invalid command: " << command << endl; } return 0; } //----------------------------------------------- // AddBook // Reads title and author from file, echos command // and adds the book to the library //----------------------------------------------- void AddBook (ifstream& infile, Library& library) { string title, author; ReadLine (infile, title); ReadLine (infile, author); cout << "ADDBOOK: " << title << ", " << author << endl; library.AddBook (title, author); } //-------------------------------------------- // AddPatron // reads patron info from the file // echos command and adds patron to library //-------------------------------------------- void AddPatron (ifstream& infile, Library& library) { string name; ReadLine (infile, name); cout << "COMMAND:ADDPATRON, "<< name << endl; library.AddPatron (name); } //-------------------------------------------- // Books // Prints all books in the library //------------------------------------------- void Books ( ifstream& in, Library& library) { cout << "COMMAND:BOOKS" << endl; library.ListBooks( ); } //---------------------------------------------- // CheckIn // reads title from input file, echos // command and checks in book //---------------------------------------------- void CheckIn (ifstream &infile, Library& library) { string title; ReadLine (infile, title); cout << "COMMAND:CHECKIN, " << title << endl; library.CheckIn (title); } //------------------------------------------------- // CheckOut // Reads title and patron from file, echos command // checks out book if no errors detected //------------------------------------------------- void CheckOut (ifstream& infile, Library& library) { string title, patron; ReadLine (infile, title); ReadLine (infile, patron); cout << "CHECKOUT: " << title << ", " << patron << endl; library.CheckOut (title, patron); } //--------------------------------------- // Patrons // Lists all patrons in the library //----------------------------------------- void Patrons ( ifstream& in, Library& library) { cout << "COMMAND:PATRONS" << endl; library.ListPatrons( ); } //------------------------------------------------ // PatronsBooks // Reads patron's name from file and lists // books he has checkedout of library //------------------------------------------------ void PatronsBooks (ifstream& infile, Library& library) { string name; ReadLine (infile, name); cout << "COMMAND:PATRONSBOOKS, " << name << endl; library.ListPatronsBooks (name); } //------------------------------------------------ // ReadLine // skips blank lines in the file // returns true if non-blank line read (and s = "") // returns false on eof (and s contains string read) //------------------------------------------------- bool ReadLine (ifstream& in, string& s) { s = ""; // empty string with length==0 // loop until eof or non-blank string read while (!in.eof( ) && s.length() == 0) { getline (in, s); if (s.length() != 0) return true; } // eof return false; }