// All of the parameters are by-reference for performance reasons. // Note the use of overloading, templates, STL, and sequential file I/O. #include #include #include #include using namespace std; // -------------------------------------------------------------------------------- class Customer { friend ostream &operator<<(ostream&, const Customer); friend istream &operator>>(istream&, Customer&); public: string f_name; string l_name; }; ostream &operator<<(ostream& output, const Customer C) { output << C.f_name << " " << C.l_name; return output; } istream &operator>>(istream& input, Customer& C) { input >> C.f_name >> C.l_name; return input; } // -------------------------------------------------------------------------------- class Item { friend ostream &operator<<(ostream&, const Item); friend istream &operator>>(istream&, Item&); public: string description; }; ostream &operator<<(ostream& output, const Item I) { output << I.description; return output; } istream &operator>>(istream& input, Item& I) { char buffer[255]; input.getline(buffer, 255); I.description = buffer; return input; } // -------------------------------------------------------------------------------- class Order { friend ostream &operator<<(ostream&, const Order); friend istream &operator>>(istream&, Order&); public: int item_id; int customer_id; }; ostream &operator<<(ostream& output, const Order O) { output << O.item_id << " " << O.customer_id; return output; } istream &operator>>(istream& input, Order& O) { input >> O.item_id >> O.customer_id; return input; } // -------------------------------------------------------------------------------- typedef map Customer_Table; typedef map Item_Table; typedef multimap Order_Table; // -------------------------------------------------------------------------------- template void PrintTable(map& m) { map::const_iterator i; for (i=m.begin(); i != m.end(); i++) cout << i->first << " " << i->second << endl; } // -------------------------------------------------------------------------------- template void ReadTable(string file_name, map& t_table) { ifstream ifp; int id; T t; ifp.open(file_name.c_str(), ios::in); if (!ifp) { cerr << "Error - '" << file_name << "' could not be opened" << endl; exit(1); } while (ifp >> id >> t) { t_table[id] = t; } ifp.close(); } // -------------------------------------------------------------------------------- template void PrintTable(multimap& m) { multimap::const_iterator i; for (i=m.begin(); i != m.end(); i++) cout << i->first << " " << i->second << endl; } // -------------------------------------------------------------------------------- template void ReadTable(string file_name, multimap& t_table) { ifstream ifp; int id; T t; ifp.open(file_name.c_str(), ios::in); if (!ifp) { cerr << "Error - '" << file_name << "' could not be opened" << endl; exit(1); } while (ifp >> id >> t) { t_table.insert(multimap::value_type(id, t)); } ifp.close(); } // -------------------------------------------------------------------------------- void PrintSummary(Customer_Table& Customers, Item_Table& Items, Order_Table& Orders) { Order_Table::const_iterator i; int order_id = Orders.begin()->first + 1; for (i=Orders.begin(); i != Orders.end(); i++) { if (order_id != i->first) { cout << endl << "Order : " << i->first << endl; cout << "Customer : " << Customers[i->second.customer_id] << endl; cout << "Item(s) :" << Items[i->second.item_id] << endl; order_id = i->first; } else cout << " " << Items[i->second.item_id] << endl; } } // -------------------------------------------------------------------------------- void PrintReport (Customer_Table& Customers, Item_Table& Items, Order_Table& Orders) { cout << "CUSTOMERS TABLE" << endl; cout << "---------------" << endl; PrintTable(Customers); cout << endl << endl; cout << "ITEMS TABLE" << endl; cout << "-----------" << endl; PrintTable(Items); cout << endl << endl; cout << "CRYPTIC ORDERS TABLE" << endl; cout << "--------------------" << endl; PrintTable(Orders); cout << endl << endl; cout << "ORDERS SUMMARY TABLE" << endl; cout << "--------------------" << endl; PrintSummary(Customers, Items, Orders); } // -------------------------------------------------------------------------------- // CleanUp isn't really necessary since the map & multimap destructors will do this void CleanUp(Customer_Table& Customers, Item_Table& Items, Order_Table& Orders) { Customers.empty(); Items.empty(); Orders.empty(); } // -------------------------------------------------------------------------------- // Imagine running this from command-line and piping output to another file. // This would be a good way to automate some DB functions & reporting. int main (void) { Customer_Table Customers; Item_Table Items; Order_Table Orders; ReadTable("Customers.txt", Customers); ReadTable("Items.txt", Items); ReadTable("Orders.txt", Orders); PrintReport(Customers, Items, Orders); CleanUp(Customers, Items, Orders); return 0; }