// FILE: files3.cpp // PURPOSE: file operations with overloaded << and >> for Customer class // OTHER FILES: apvector.h, apvector.cpp, //--------------------------------------------------------------------- // COMPILATION INSTRUCTIONS: g++ and gxx // 1. FILES: apvector.h, apvector.cpp must // be in folder or directory in which you compile // 2. COMMAND LINE: // g++ (or gxx) files3.cpp //--------------------------------------------------------------------- //--------------------------------------------------------------------- // PROGRAMMING INSTRUCTIONS: // 1. Complete the three Customer constructors and the operator= function // and run the program to validate // 2. Implement the overloaded stream operator functions as specified below // 3. After you've completed Parts 1-2, complete readFile and writeFile // as specified below // 4. Complete templated selection sort function started below // 5. Complete templated binary search function started below // 6. Examine withDrawDriver and use as a model for completing depositDriver // 7. Complete deleteCustomer (using binary search function) as specified // 8. Complete addCustomer (using a sequential search) as specified //--------------------------------------------------------------------- #include #include #include "apvector.h" #include class Customer { public: Customer(void); Customer(const string &, double = 0.0); Customer (const Customer &); string getName(void) const; double getBalance(void)const; void printData(void) const; Customer &operator=(const Customer &); private: string name; double balance; }; ostream &operator << (ostream &, const Customer &); ostream &operator >> (istream &, const Customer &); bool operator > (const string &, const Customer &); bool operator < (const string &, const Customer &); void assignmentDriver(void); void inFileDriver(apvector &, const string &); void readFile(apvector &); void writeFile(apvector &, const string & ); bool sortTest(const apvector &); void outFileDriver(apvector &, const string &); void sortDriver(apvector &); void withdrawDriver(apvector &); void addCustomer(apvector &); void deleteCustomer(apvector &); void loadVec(apvector &); void printVec(const apvector &, const string &); void menu(char &); void bSearchDriver(const apvector &); void depositDriver(apvector &); void cls(void); void wait(void); const string dataFile("files3.txt"); Customer::Customer(void) : name("Default: no name"), balance(0.0) {} Customer::Customer(const string &name2, double balance2): name(name2), balance(balance2) {} Customer::Customer(const Customer &customer): name(customer.name), balance(customer.balance) {} Customer &Customer::operator=(const Customer &right) { //postcondition: 1. LHS (the owner) gets right's name and balance // 2. Supports chaining } //------------------------------------------------------- // STREAM OPERATOR FUNCTIONS //------------------------------------------------------- ostream &operator<<(ostream &os, const Customer &right) { os << right.getName() << '\t' << right.getBalance(); return os; } istream &operator>>(istream &is, Customer &right) { // To enable use with files, do NOT prompt user string name; double balance; is >> name >> balance; right = Customer(name, balance); return is; } void readFile(apvector &v, const string &fileName) { // precond: file fileName.c_str() exists and contains 1 or more Customer objects // must create and open ifstream object //postcond: contents of fname read into vector v, file closed } void writeFile(apvector &v, const string &fileName) { // precond: fileName.c_str() is name of file to create // must create and open ofstream object //postcond: contents of v writtten to dataFile, file closed } bool operator > (const Customer &left, const Customer &right) { return ( left.getName() > right.getName() ); } bool operator > (const string &left, const Customer &right) { return ( Customer(left, 0.0) > right ); } bool operator < (const string &left, const Customer &right) { return ( right.getName() > Customer(left, 0.0)); } bool operator < (const Customer &left, const Customer &right) { return ( left.getName() < right.getName() ); } template // *** uses selection sort algorithm void selSort(apvector &v) { // precondition: operator < is implemented for class U //postcondition: v's elements are in ascending order const int SIZE = v.length(); } template // *** uses binary seach algorithm int bSearch(const apvector &v, const string &key) { // precondition: v's elements are in ascending order //postcondition: when key == v[mid] in specified for class U, // its index is returned; otherwise -1 is returned int lo(0), hi(v.length()-1); return -1; } void deleteCustomer(apvector &V) { // precondition: bSearch() works!! //postcondition: if found, specified Customer object is removed by // shifting all successors (if any) forward and V is resized accordingly // EXAMPLE deleting L: A D G K L M Q X ----> A D G K M Q X // 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 string name; cout << "Enter name of customer to delete: "; getline(cin, name); } void addCustomer(apvector &V) { // HINT: don't use bSearch()--use a linear search here!! //postcondition: specified Customer object is added by shifting // all successors (if any) back and V is resized accordingly // EXAMPLE adding L: A D G K M Q X ----> A D G K L M Q X // 0 1 2 3 4 5 6 0 1 2 3 4 5 6 7 const int SIZE(V.length()); string name; cout << "Enter name of customer to add: "; getline(cin, name); } void withdrawDriver(apvector &V) { // precondition: bSearch() function works!!! //postcondition: this is the counterpart to depositDriver(). Therefore // use depositDriver() as a model to complete this function string name; cout << "Enter customer name: "; getline(cin, name); int index = bSearch(V, name); if ( index < 0 ) { cout << name << " not found.\n"; } else { cout << "Enter amount to withdraw: "; double amount; cin >> amount; cin.ignore(10, '\n'); V[index] = Customer(name, V[index].getBalance() - amount); cout << "New balance is: " << V[index].getBalance() << endl; } } void depositDriver(apvector &V) { string name; cout << "Enter customer name: "; getline(cin, name); } int main(void) { apvector cVec; char ch; //loadVec(cVec); do { printVec(cVec, ""); menu(ch); switch( ch ) { case '1': assignmentDriver(); break; case '2': inFileDriver(cVec, dataFile); break; case '3': sortDriver(cVec); break; case '4': bSearchDriver(cVec); break; case '5': depositDriver(cVec); break; case '6': withdrawDriver(cVec); break; case '7': addCustomer(cVec); break; case '8': deleteCustomer(cVec); break; case '9': outFileDriver(cVec, dataFile); break; case '0': return 0; default: break; } // switch cout << "Press to continue..."; cin.ignore(80, '\n'); } while (ch != '0'); cout << endl << endl; return 0; }//*** main ////////////////////////////////////////////////////////////////////// // free (non-member) functions that have been defined ////////////////////////////////////////////////////////////////////// void inFileDriver(apvector &V, const string &fileName) { string title("Creating or loading input file: " + fileName); cls(); cout << setw(39 + title.length()/2) << title.c_str() << endl << endl; char ch; do { cout << "\nLoad " << fileName << " (if you previously created it) " << "or create new file\n" << "Load or Create? (L/C): "; cin.get(ch); ch = ch | 32; if ( ch == 'l' ) { readFile(V, fileName); } else if ( ch == 'c' ) { loadVec(V); writeFile(V, fileName); readFile(V, fileName); } } while ( ch != 'l' && ch != 'c' ); cin.ignore(10, '\n'); sortTest(V); printVec(V, ""); } void outFileDriver(apvector &V, const string &fileName) { string title("Creating output file: " + fileName); cls(); cout << setw(39 + title.length()/2) << title << endl << endl; char ch; do { cout << "\nWrite data in current vector or write an empty file:\n" << "Current vector or zero element file (C/Z): "; cin.get(ch); ch = ch | 32; if ( ch == 'z' ) { V.resize(0); writeFile(V, fileName); } else if ( ch == 'c' ) { writeFile(V, fileName); } } while ( ch != 'z' && ch != 'c' ); cin.ignore(10, '\n'); sortTest(V); printVec(V, ""); } void sortDriver(apvector &V) { string title("Sort Driver"); cls(); cout << setw(39 + title.length()/2) << title << endl << endl; string msg; bool isSorted = sortTest(V); if ( isSorted ) msg = "Data is sorted"; else msg = "Data is NOT sorted."; printVec(V, msg); selSort(V); isSorted = sortTest(V); if ( isSorted ) msg = "Data is sorted"; else msg = "Data is NOT sorted."; printVec(V, msg); } bool sortTest(const apvector &v) { const int SIZE = v.length(); for (int k = 0; k < SIZE - 1; k++) { if ( v[k] > v[k+1] ) return false; } return true; } void assignmentDriver(void) { string title("Testing overloaded assignment operators and constructors"); cls(); cout << setw(39 + title.length()/2) << title << endl << endl; Customer A; cout << "Testing default constructor: Customer A;\n"; cout << "Customer object A = "; A.printData(); cout << "\n\n"; Customer B("Pat See", 123.45); cout << "Testing explicit value constructor: " << "Customer B(\"Pat See\", 123.45);\n"; cout << "Customer object B = "; B.printData(); cout << "\n\n"; Customer C(B); cout << "Testing copy constructor: Customer C(B);\n"; cout << "Customer object C = "; C.printData(); cout << "\n\n"; Customer X("Pat", 123.45), Y, Z; cout << "BEFORE STATEMENT z = y = x;\n"; cout << "Customer object X = "; X.printData(); cout << "\nCustomer object Y = "; Y.printData(); cout << "\nCustomer object Z = " ; Z.printData(); cout << endl; Z = Y = X; cout << "AFTER STATEMENT z = y = x;\n"; cout << "Customer object X = "; X.printData(); cout << "\nCustomer object Y = "; Y.printData(); cout << "\nCustomer object Z = " ; Z.printData(); cout << endl << endl; } void loadVec(apvector &A) { Customer list[] = { Customer("Latham", 23.23), Customer("Zamansky", 260.26), Customer("Wong", 2920.20), Customer("Ferrara", 666.77), Customer("Geller", 7000), Customer("Winokur",757.99), Customer("Platek", 15.15), Customer("Simion", 1919.19), Customer("Jaye", 1267.13), Customer("Liang", 1199.88) }; const int SIZE = sizeof(list)/sizeof(Customer); A.resize(SIZE); for (int k = 0; k < SIZE; k++) { A[k] = list[k]; } } void printVec(const apvector &A, const string &msg) { cls(); cout << msg << endl; const int ColSIZE = 12; const int SIZE = A.length(); for (int k = 0; k < SIZE; k++) cout << setw(20) << k << " " << A[k].getName() << setw(ColSIZE - A[k].getName().length()) << "" << setiosflags(ios::fixed | ios::right) << setprecision(2) << setw(7) << A[k].getBalance() << endl; if ( SIZE == 0 ) cout << "No data...." << endl; cout << endl; } void menu(char &choice) { const string TAB("\t\t\t"); cout << TAB << " Bank Customer List Operations\n"; cout << TAB << "----------------------------------\n"; cout << TAB << "Test operator= and constructors 1\n"; cout << TAB << "Create or load file files3.txt 2\n"; cout << TAB << "Sort customers 3\n"; cout << TAB << "Binary search on customer name 4\n"; cout << TAB << "Make a deposit 5\n"; cout << TAB << "Make a withdrawal 6\n"; cout << TAB << "Add a new customer 7\n"; cout << TAB << "Delete a customer 8\n"; cout << TAB << "Write data to files3.txt 9\n"; cout << TAB << "Quit program 0\n"; cout << TAB << "----------------------------------\n"; cout << TAB << " SELECTION==> "; for (;;) { cin.get(choice); cin.ignore(10, '\n'); if ( choice < '0' || choice > '9' ) cout << TAB << "*** Invalid choice. Try again: "; else break; } } //*** menu void bSearchDriver(const apvector &V) { string name; cout << "Enter customer name to be searched: "; getline(cin, name); int index = bSearch(V, name); if ( index < 0 ) cout << name << " not found.\n"; else { cout << name << " found at index position " << index << ", Balance = " << V[index].getBalance() << endl; } } ////////////////////////////////////////////////////////////////////// // member functions that have been defined ////////////////////////////////////////////////////////////////////// string Customer::getName(void) const { return name; } double Customer::getBalance(void)const { return balance; } void Customer::printData(void) const { cout << "[name: " << name << ", balance: " << balance << "]"; } void wait (void) { cout << "Press ..."; cin.ignore(10, '\n'); } void cls(void) { for (int k = 1; k <= 55; k++) cout << endl; }