A command-line client for interacting with "book" and "member" servers via XMLRPC calls. Servers were created by other students.

xmlrpc_client.cpp 25KB

    #include <string> #include <iostream> #include <iomanip> #include <stdio.h> #include <fstream> #include "BookstoreCaller.h" #include "menu.h" using namespace std; #define PAUSE { for(; cin.get() != '\n'; ) ;} #define CLEANIN { for(; cin.get() != '\n'; ) ;} // PROTOTYPES void PrintUsage(string programName); // print program usage message // Menu item functions void book_purchase(); // purchase a single book void mem_add(); // interactively add a member void mem_retrieve(); // retrieve and display a single member void mem_list(); // display all members void mem_delete(); // deletes a member for the membership list void mem_list_clear(); // empty/clear member list void book_add(); // add a single book void book_inv(); // update inventory for a book void book_retrieve(); // retrieve and display a single book void book_list(); // display all books void book_list_clear(); // empty/clear the book list void book_list_read(); // read a data file into the book list void book_list_write(); // write the book list to a data file void mem_list_read(); // read a data file into the member list void mem_list_write(); // write the member list to a data file*/ // I/O control void DecimalPrecision(); // set precision(2), fixed void NormalPrecision(); // set precision(0), fixed // global BookstoreCaller since it cannot be handed to each menu function BookstoreCaller caller; int main(int argc, char* argv[]) { // set output for floats to FIXED (not scientific) notation and 2 decimal places past zero cout << fixed << setprecision(2); // Usage if( argc >= 5 ) { // Member Server Address string memAddr = argv[1]; // Member Server Port string memPort = argv[2]; // Book Server Address string bookAddr = argv[3]; // Book Server Port string bookPort = argv[4]; BookstoreCaller tempCaller = BookstoreCaller(memAddr, memPort, bookAddr, bookPort); caller = tempCaller; } else { PrintUsage(argv[0]); cerr << argv[0] << " is exiting.\n"; return 1; } BookType b; b.ISBN("SOMEOTHERBOOK"); b.Title("Some other book"); b.Stock(15); b.Price(22.22); b.Publisher("Publisher Guy That does stuff"); b.PublicationYear(2010); b.AddAuthor("Some guy"); b.AddAuthor("some guy toooo"); b.AddAuthor("author dude"); caller.UpdateBook(b); if( caller.IsBookServerUp() ) cout << "Book server is up and connected at \'" << caller.BookFullAddress() << "\'.\n"; if( caller.IsMemberServerUp() ) cout << "Member server is up and connected at \'" << caller.MemberFullAddress() << "\'.\n"; Menu main_menu, // main menu object mem_maint_menu, // submenu for member maintanence bk_maint_menu, // submenu for book maintanence file_menu; // submenu for file I/O of book and member information // Populate main menubook main_menu.install_title((char*)"Group 5's CSIS 440 XMLRPC Bookstore"); main_menu.install_entry((char*)"Book Purchase", book_purchase); main_menu.install_entry((char*)"Member List Maintanence", & mem_maint_menu); main_menu.install_entry((char*)"Book List Maintanence", & bk_maint_menu); main_menu.install_entry((char*)"File Maintanence", & file_menu); // Populate the member maintanence submenu mem_maint_menu.install_title((char*)"Member Maintanence"); mem_maint_menu.install_entry((char*)"Add Member", mem_add); mem_maint_menu.install_entry((char*)"Display Member", mem_retrieve); mem_maint_menu.install_entry((char*)"Display Member List", mem_list); mem_maint_menu.install_entry((char*)"Delete Member", mem_delete); mem_maint_menu.install_entry((char*)"Clear Member List", mem_list_clear); // Populate the book maintanence submenu bk_maint_menu.install_title((char*)"Book Maintanence"); bk_maint_menu.install_entry((char*)"Add New Book", book_add); bk_maint_menu.install_entry((char*)"Update Inventory", book_inv); bk_maint_menu.install_entry((char*)"Display A Book", book_retrieve); bk_maint_menu.install_entry((char*)"Display Book List", book_list); bk_maint_menu.install_entry((char*)"Clear Book List", book_list_clear); // Populate the file submenu file_menu.install_title((char*)"File Management"); file_menu.install_entry((char*)"Read Book File", book_list_read); file_menu.install_entry((char*)"Read Member File", mem_list_read); file_menu.install_entry((char*)"Write Book File", book_list_write); file_menu.install_entry((char*)"Write Member File", mem_list_write); if( caller.IsBookServerUp() || caller.IsMemberServerUp() ) { // launch menu cout << "Please press \"Enter\" to launch menu.\n"; PAUSE; main_menu.run(); cout << "Menu terminated gracefully. Client is shutting down.\n"; } else { cout << "Neither server is up. Nothing to do. Client is shutting down.\n"; } return 0; /* BookType b; b.ISBN("SOMEOTHERBOOK"); b.Title("Some other book"); b.Stock(3); b.Price(22.22); b.Publisher("Publisher Guy That does stuff"); b.PublishedYear(2010); b.AddAuthor("Some guy"); b.AddAuthor("some guy toooo"); b.AddAuthor("author dude"); cout << caller.AddBook(b) << endl; b.Price(9001.0); cout << caller.UpdateBook(b) << endl; BookType bb = caller.LookupBook(b.ISBN()); cout << "looked up: " << bb.ISBN() << endl; cout << caller.DeleteBook(b.ISBN()) << endl; */ MemberType m; m.ID("123"); m.FirstName("First"); m.LastName("Last"); while(1) { cout << caller.AddMember(m) << endl; caller.MemberList(); } /* m.FirstName("NewFirst"); cout << caller.UpdateMember(m) << endl; MemberType mm = caller.LookupMember("123"); cout << "looked up: " << mm.ID() << endl; cout << caller.DeleteMember("123") << endl; caller.MemberList(); map<string, MemberType> mappy = caller.Members(); map<string, MemberType>::iterator iter, back; iter = mappy.begin(); back = mappy.end(); for(; iter != back; iter++) { cout << (*iter).first << endl; }*/ /*caller.BookList(); map<string, BookType> mappy = caller.Books(); map<string, BookType>::iterator iter, back; iter = mappy.begin(); back = mappy.end(); for(; iter != back; iter++) { cout << (*iter).first << endl; } */ return 0; } void PrintUsage(string programName) { cerr << "Usage: " << programName << " <Member Server Address> <Member Server Port> <Book Server Address> <Book Server Port>\n" << "\tNote: Providing 0 for either an address or a port will tell the client to not connect to that server type.\n" << "\tNo operations dealing with that server will be allowed.\n"; } void NormalPrecision() { cout << fixed << setprecision(0); } void DecimalPrecision() { cout << fixed << setprecision(2); } // --- MENU FUNCTIONS --- void book_purchase() { MemberType m; bool isMember = false; cout << "-: Book Purchase :-\n"; if( !caller.IsBookServerUp() ) { cout << "Book server is not up. Cannot use this functionality.\n"; cout << "Please press \"Enter\"..."; PAUSE; return; } // ask if member cout << "Are you a member? [Y/N] :"; char ANSWER; cin >> ANSWER; CLEANIN; // if member, ask for ID and fetch MEMBER if( ANSWER == 'y' || ANSWER == 'Y' ) { if( !caller.IsMemberServerUp() ) { cout << "Member server is not up. Cannot use this functionality.\n"; cout << "Do you wish to continue without membership? [Y/N] : "; cin >> ANSWER; CLEANIN; if( ANSWER == 'y' || ANSWER == 'Y' ) { cout << "Continuing without membership.\n"; } else { cout << "Please press \"Enter\"..."; PAUSE; return; } } if( caller.IsMemberServerUp() ) { cout << "What is your user ID? :"; string id = ""; cin >> id; CLEANIN; m = caller.LookupMember(id); if( m.ID() == id ) { cout << "Member found by id " << id << endl; cout << "Hello, " << m.FirstName() << " " << m.LastName() << ".\n"; isMember = true; } } } else { cout << "Continuing without member privileges.\n"; } // ask for ISBN cout << "ISBN of the book you wish to purchase? :"; string isbn = ""; cin >> isbn; CLEANIN; // fetch BOOK BookType b = caller.LookupBook(isbn); if( b.ISBN() == isbn ) { DecimalPrecision(); cout << "Book found. \'" << b.Title() << "\' for $" << b.Price() << endl; NormalPrecision(); } else { cout << "Book was not found with ISBN \'" << isbn << "\'. Returning to menu.\n"; PAUSE; return; } // check stock cout << b.Stock() << " copies in stock of this book.\n"; if( b.Stock() == 0) { cout << "You cannot buy a book with no copies in stock. Returning to menu.\n"; PAUSE; return; } // if member, do MEMBER OPS (check discount, do discount, add book bought if not discount, add spent if not discount) if( isMember ) { if( m.ReadyForDiscount() ) { float discount = m.DiscountAmount(); DecimalPrecision(); cout << "You are ready for a discount! You saved $" << discount << " on this book!\n"; cout << "Book's final price is $" << (b.Price() - discount) << ".\n"; // reset the member's totals m.DiscountReset(); NormalPrecision(); } else { m.BuyBook( b.Price() ); cout << "No discount this time. You have purchased " << m.BooksBought() << " books\n"; } } // update BOOK for stock b.Stock( b.Stock() - 1 ); // update BOOK if( caller.UpdateBook(b) ) { // update MEMBER if( !caller.UpdateMember(m) ) { cout << "Could not update member. Complain to your system admin.\n"; } } else { cout << "Could not update book. Complain to your system admin.\n"; } cout << "Book purchase complete. Returning to menu.\n"; cout << "Please press \"Enter\"..."; PAUSE; } void mem_add() { // get info from user cout << "-: Add Member :-\n"; if( !caller.IsMemberServerUp() ) { cout << "Member server is not up. Cannot use this functionality.\n"; cout << "Please press \"Enter\"..."; PAUSE; return; } string fname, lname, id; cout << "ID :"; cin >> id; CLEANIN; // check if ID is in use after getting ID MemberType m; m = caller.LookupMember(id); if( m.ID() == id) { cout << "Member with id \'" << id << "\' exists already. Cannot add new member.\n"; } else { cout << "First name: "; cin >> fname; CLEANIN; cout << "Last name: "; cin >> lname; CLEANIN; // if not in use, add member m.ID(id); m.FirstName(fname); m.LastName(lname); if( caller.AddMember(m) ) { cout << "New member successfully added.\n"; } else { cout << "Could not add member. Complain to your system admin.\n"; } } cout << "Add member complete. Returning to menu.\n"; cout << "Please press \"Enter\"..."; PAUSE; } void mem_retrieve() { cout << "-: Lookup Member :-\n"; if( !caller.IsMemberServerUp() ) { cout << "Member server is not up. Cannot use this functionality.\n"; cout << "Please press \"Enter\"..."; PAUSE; return; } // ask for ID string id; cout << "ID :"; cin >> id; CLEANIN; // fetch MEMBER MemberType m = caller.LookupMember(id); // display MEMBER if( m.ID() == id ) { cout << "-Member Information-\n" << "ID: " << m.ID() << endl << m.LastName() << ", " << m.FirstName() << endl << "Books bought: " << m.BooksBought() << endl << "Money spent: " << m.MoneySpent() << endl << endl; } else { cout << "Member not found with id \'" << id << "\'.\n"; } cout << "Member lookup complete. Returning to menu.\n"; cout << "Please press \"Enter\"..."; PAUSE; } void mem_list() { cout << "-: Member List :-\n"; if( !caller.IsMemberServerUp() ) { cout << "Member server is not up. Cannot use this functionality.\n"; cout << "Please press \"Enter\"..."; PAUSE; return; } // get latest MEMBER list map<string, MemberType> mappy = caller.MemberList(); // tabulate it all map<string, MemberType>::iterator iter, back; iter = mappy.begin(); back = mappy.end(); string nameSeparater = ", "; for(; iter != back; iter++) { MemberType m = (*iter).second; string name = m.LastName() + nameSeparater + m.FirstName(); cout << setw(8) << m.ID() << "\t" << setw(36) << name << "\t" << setw(2) << m.BooksBought() << "\t" << m.MoneySpent() << endl; } cout << "\n" << "Member listing complete. Returning to menu.\n"; cout << "Please press \"Enter\"..."; PAUSE; } void mem_delete() { cout << "-: Delete Member :-\n"; if( !caller.IsMemberServerUp() ) { cout << "Member server is not up. Cannot use this functionality.\n"; cout << "Please press \"Enter\"..."; PAUSE; return; } // ask for ID string id; cout << "ID :"; cin >> id; CLEANIN; // try to delete MEMBER if( caller.DeleteMember(id) ) { cout << "Member successfully removed with the id \'" << id << "\'.\n"; } else { cout << "Member does not exist, or could not be deleted, that had the id \'" << id << "\'.\n"; } cout << "Member deletion complete. Returning to menu.\n"; cout << "Please press \"Enter\"..."; PAUSE; } void mem_list_clear() { cout << "-: Clear Member List :-\n"; if( !caller.IsMemberServerUp() ) { cout << "Member server is not up. Cannot use this functionality.\n"; cout << "Please press \"Enter\"..."; PAUSE; return; } // get latest MEMBER list map<string, MemberType> mappy = caller.MemberList(); if( caller.MemberCount() == 0 ) { cout << "No members to delete.\n"; } else { // for_each delete MEMBER map<string, MemberType>::iterator iter, back; iter = mappy.begin(); back = mappy.end(); int count = 0; for(; iter != back; iter++) { // get the member, and send the delete command // report an error if unable to delete the member if ( caller.DeleteMember( (*iter).second ) ) { cout << "Member with id \'" << (*iter).first << "\' could not be deleted.\n"; } else { count++; } } cout << count << " members deleted. " << (caller.MemberCount() - count) << " not deleted.\n"; } cout << "Member list deletion complete. Returning to menu.\n"; cout << "Please press \"Enter\"..."; PAUSE; } void book_add() { cout << "-: Add Book :-\n"; if( !caller.IsBookServerUp() ) { cout << "Book server is not up. Cannot use this functionality.\n"; cout << "Please press \"Enter\"..."; PAUSE; return; } // get info from user string isbn, title, publisher, auth = ""; float price = 0.0; int stock = 0; int pubYear = 0; cout << "ISBN: "; cin >> isbn; CLEANIN; BookType b; /* This section is removed to deal with a Joe's Book Server giving back an object that causes XMLRPC-C's assert to explode the program. Unavoidable bug. */ /* // check if ISBN is in use after getting ISBN b = caller.LookupBook(isbn); if( b.ISBN() == isbn ) { cout << "Book with ISBN \'" << isbn << "\' already exists. Cannot add book.\n"; } else { */ // if not in use, add book cout << "Title: "; getline(cin, title); // CLEANIN; cout << "Publisher: "; cin >> publisher; CLEANIN; cout << "Publication Year: "; cin >> pubYear; CLEANIN; cout << "Stock: "; cin >> stock; CLEANIN; cout << "Price: "; cin >> price; CLEANIN; vector<string> authors; string delim = "=="; cout << "To stop inputting authors, please hit input \"" << delim << "\".\n"; for(int i = 0; i < BOOKTYPE_MAX_AUTHORS; i++) { cout << "Author" << i+1 << ": "; getline(cin, auth); if( auth == delim ) { break; } authors.push_back(auth); auth = ""; } b.ISBN(isbn); b.Title(title); b.Publisher(publisher); b.PublicationYear(pubYear); b.Stock(stock); b.Price(price); for(int i = 0; i < authors.size(); i++) { b.AddAuthor(authors[i]); } cout << "Adding book... "; if( caller.AddBook(b) ) { cout << "Book added with ISBN \'" << isbn << "\'.\n"; } else { cout << "Book could not be added. Complain to your system admin.\n"; } // } cout << "Add book complete. Returning to menu.\n"; cout << "Please press \"Enter\"..."; PAUSE; } void book_inv() { cout << "-: Update Book :-\n"; if( !caller.IsBookServerUp() ) { cout << "Book server is not up. Cannot use this functionality.\n"; cout << "Please press \"Enter\"..."; PAUSE; return; } // ask for ISBN string isbn; cout << "ISBN: "; cin >> isbn; CLEANIN; // fetch BOOK BookType b = caller.LookupBook(isbn); if( b.ISBN() == isbn ) { string isbn, title, publisher, auth = ""; float price = 0.0; int stock = 0; int pubYear = 0; string delim = "=="; cout << "Title [" << b.Title() << "]: "; cin >> title; CLEANIN; cout << "Publisher [" << b.Publisher() << "]: "; cin >> publisher; CLEANIN; cout << "Publication Year [" << b.PublicationYear() << "]: "; cin >> pubYear; CLEANIN; cout << "Stock [" << b.Stock() << "]: "; cin >> stock; CLEANIN; cout << "Price [" << b.Price() << "]: "; cin >> price; CLEANIN; vector<string> authors; vector<string> authorsORIG = b.Authors(); cout << "To stop inputting authors, please hit \"Enter\" twice in a row.\n"; cout << "Please input \"" << delim << "\" to leave the value the same.\n"; for(int i = 0; i < BOOKTYPE_MAX_AUTHORS; i++) { cout << "Author" << i+1 << " [" << authorsORIG[i] << "]: "; getline(cin, auth); if( auth.size() == 0 ) { break; } if( auth == delim ) { authors.push_back(authorsORIG[i]); } else { authors.push_back(auth); } auth = ""; } // update the book b.Title(title); b.Publisher(publisher); b.PublicationYear( pubYear ); b.Stock(stock); b.Price(price); if( authorsORIG != authors ) { b.ClearAuthors(); for(int i = 0; i < authors.size(); i++) { b.AddAuthor( authors[i] ); } } cout << "Updating book... "; if( caller.UpdateBook(b) ) { cout << "Book updated.\n"; } else { cout << "Book could not be updated. Complain _really hard_ to your system admin.\n"; } } cout << "Update book complete. Returning to menu.\n"; cout << "Please press \"Enter\"..."; PAUSE; } void book_retrieve() { cout << "-: Lookup Book :-\n"; if( !caller.IsBookServerUp() ) { cout << "Book server is not up. Cannot use this functionality.\n"; cout << "Please press \"Enter\"..."; PAUSE; return; } // ask for ISBN string isbn; cout << "ISBN: "; cin >> isbn; CLEANIN; // fetch BOOK BookType b = caller.LookupBook(isbn); if( b.ISBN() == isbn ) { cout << "ISBN: " << b.ISBN() << endl << b.Title() << " (" << b.PublicationYear() << ")" << endl << b.Publisher() << endl << "In stock: " << b.Stock() << endl << "Price: $" << b.Price() << endl; vector<string> authors = b.Authors(); for(int i = 0; i < b.AuthorsCount(); i++) { cout << "\t" << authors[i] << endl; } } else { cout << "Book not found by ISBN \'" << isbn << "\'.\n"; } cout << "Lookup book complete. Returning to menu.\n"; cout << "Please press \"Enter\"..."; PAUSE; } void book_list() { cout << "-: Book List :-\n"; if( !caller.IsBookServerUp() ) { cout << "Book server is not up. Cannot use this functionality.\n"; cout << "Please press \"Enter\"..."; PAUSE; return; } // get latest BOOK list map<string, BookType> mappy = caller.BookList(); // tabulate it all map<string, BookType>::iterator iter, back; iter = mappy.begin(); back = mappy.end(); for(; iter != back; iter++) { BookType b = (*iter).second; NormalPrecision(); cout << setw(15) << b.ISBN() << " " << setw(20) << " \'" << b.Title() << "\' (" << setw(4) << b.PublicationYear() << ") " << setw(20) << b.Publisher() << " " <<setw(4) << b.Stock() << " "; DecimalPrecision(); cout << b.Price(); NormalPrecision(); vector<string> authors = b.Authors(); for(int i = 0; i < b.AuthorsCount(); i++) { cout << " \'" << setw(36) << authors[i] << "\'"; } cout << endl; } cout << "Book list complete. Returning to menu.\n"; cout << "Please press \"Enter\"..."; PAUSE; } void book_list_clear() { cout << "-: Clear Book List :-\n"; if( !caller.IsBookServerUp() ) { cout << "Book server is not up. Cannot use this functionality.\n"; cout << "Please press \"Enter\"..."; PAUSE; return; } // get latest MEMBER list map<string, BookType> mappy = caller.BookList(); if( caller.BookCount() == 0 ) { cout << "No books to delete.\n"; } else { // for_each delete BOOK map<string, BookType>::iterator iter, back; iter = mappy.begin(); back = mappy.end(); int count = 0; for(; iter != back; iter++) { // get the member, and send the delete command // report an error if unable to delete the member if ( caller.DeleteBook( (*iter).second ) ) { cout << "Book with ISBN \'" << (*iter).first << "\' could not be deleted.\n"; } else { count++; } } cout << count << " books deleted. " << (caller.MemberCount() - count) << " not deleted.\n"; } cout << "Book list deletion complete. Returning to menu.\n"; cout << "Please press \"Enter\"..."; PAUSE; } // FILE I/O void book_list_read() { cout << "-: Book List from File :-\n"; if( !caller.IsBookServerUp() ) { cout << "Book server is not up. Cannot use this functionality.\n"; cout << "Please press \"Enter\"..."; PAUSE; return; } cout << "I R BROKEN\n"; // get filename string filename; cout << "Input file: "; getline( cin, filename); // does it exist? ifstream f; f.open( filename.c_str() ); if( f.fail() ) { cout << "Bad filename or could not open for reading. Check the file.\n"; } else { // read from file // try to add each BOOK while( !f.eof() ) { // READ BookType b; string isbn, title, publisher = ""; int pubYear, stock = 0; float price = 0.0; f >> isbn; cout << "isbn " << isbn << endl; getline( f, title); f.ignore(1); cout << "title " << title << endl; f >> pubYear; cout << pubYear << endl; getline( f, publisher); f.ignore(1); cout << publisher << endl; f >> stock; cout << stock << endl; f >> price; cout << price << endl; string auth = ""; for(int i = 0; i < BOOKTYPE_MAX_AUTHORS; i++) { getline( f, auth); f.ignore(1); cout << auth << endl; if( auth == "|" ) break; else b.AddAuthor(auth); auth = ""; } b.ISBN( isbn ); b.Title( title ); b.Publisher( publisher ); b.Stock( stock ); b.Price( price ); if( !caller.AddBook(b) ) { cout << b.ISBN() << " \'" << b.Title() << "\' not added. Updating instead. "; if( !caller.UpdateBook(b) ) { cout << "Book not added."; } cout << endl; } } } cout << "Book list from file complete. Returning to menu.\n"; cout << "Please press \"Enter\"..."; PAUSE; } void book_list_write() { cout << "-: Book List to File :-\n"; if( !caller.IsBookServerUp() ) { cout << "Book server is not up. Cannot use this functionality.\n"; cout << "Please press \"Enter\"..."; PAUSE; return; } // get filename string filename; cout << "Output file: "; getline( cin, filename); // does it exist? ofstream f; f.open( filename.c_str() ); if( f.fail() ) { cout << "Bad filename or could not open for writing. Check the file.\n"; } else { cout << "Starting write to file \'" << filename << "\'.\n"; // write to file for_each book map<string, BookType> mappy = caller.BookList(); map<string, BookType>::iterator iter, back; iter = mappy.begin(); back = mappy.end(); for(; iter != back; iter++) { BookType b = (*iter).second; f << fixed << setprecision(0); f << b.ISBN() << "\n" << b.Title() << "\n" << b.PublicationYear() << "\n" << b.Publisher() << "\n" << b.Stock() << "\n"; f << fixed << setprecision(2); f << b.Price(); f << fixed << setprecision(0); vector<string> authors = b.Authors(); f << endl; for(int i = 0; i < b.AuthorsCount(); i++) { f << "\t" << authors[i] << endl; } f << "\t|" << endl; } } cout << "Book list to file complete. Returning to menu.\n"; cout << "Please press \"Enter\"..."; PAUSE; } void mem_list_read() { cout << "-: Member List from File :-\n"; if( !caller.IsMemberServerUp() ) { cout << "Member server is not up. Cannot use this functionality.\n"; cout << "Please press \"Enter\"..."; PAUSE; return; } cout << "I R BROKEN\n"; // get filename string filename; cout << "Input file: "; getline( cin, filename); // does it exist? ifstream f; f.open( filename.c_str() ); if( f.fail() ) { cout << "Bad filename or could not open for reading. Check the file.\n"; } else { // read from file // try to add each BOOK while( !f.eof() ) { // READ MemberType m; string id, fname, lname = ""; int books= 0; float spent = 0.0; f >> id; f >> lname; f >> fname; f >> books; f >> spent; m.ID(id); m.LastName(lname); m.FirstName(fname); m.BooksBought(books); m.MoneySpent(spent); if( !caller.AddMember(m) ) { cout << m.ID() << " \'" << m.LastName() << ", " << m.FirstName() << "\' not added. Updating instead. "; if( !caller.UpdateMember(m) ) { cout << "Member not added."; } cout << endl; } } } cout << "Member list from file complete. Returning to menu.\n"; cout << "Please press \"Enter\"..."; PAUSE; } void mem_list_write() { cout << "-: Member List to File :-\n"; if( !caller.IsMemberServerUp() ) { cout << "Member server is not up. Cannot use this functionality.\n"; cout << "Please press \"Enter\"..."; PAUSE; return; } // get filename string filename; cout << "Output file: "; getline( cin, filename); // does it exist? ofstream f; f.open( filename.c_str() ); if( f.fail() ) { cout << "Bad filename or could not open for writing. Check the file.\n"; } else { cout << "Starting write to file \'" << filename << "\'.\n"; // get latest MEMBER list // write each MEMBER to file map<string, MemberType> mappy = caller.MemberList(); map<string, MemberType>::iterator iter, back; iter = mappy.begin(); back = mappy.end(); for(; iter != back; iter++) { MemberType m = (*iter).second; f << m.ID() << endl << m.LastName() << endl << m.FirstName() << endl << m.BooksBought() << endl << m.MoneySpent() << endl; } } cout << "Book list to file complete. Returning to menu.\n"; cout << "Please press \"Enter\"..."; PAUSE; }