/************************************* Author: Steven Scott** Filename: pex6.cpp** Date: Nov 19, 2007** Purpose: Keep track of inventory** levels for a company using linked** lists.***********************************/#include <iostream>#include <iomanip>#include <list>using namespace std;/******************************* Struct for pending items.*****************************/struct pendingItem { int pending; string customer; pendingItem *nextItem;};/******************************************* Define named constants******************************************/const int maxWidgets = 500;const int minWarning = static_cast<int>(maxWidgets * 0.1);const int pendingLimit = 100;const char cList = 'L';const char cReq = 'R';const char cShip = 'S';const char cQuit = 'Q';const char cHelp = 'H';/************************************************* Ok, now tell me if you recommend this now?** Define functions for later use.***********************************************//************************************* Function: drawMenu()** Description: Draws the help menu.***********************************/void drawMenu();/************************************* Function: getCmdAndParse() (Happy?)** Description: Takes users input,** calls whichever function they requested.***********************************/bool getCmdAndParse(int &widgets, int &accepted, int &returned, int &sent, int &maxpending, int &pending, list<pendingItem> &pendingList);/************************************* Function: listInv()** Description: Prints inventory** and pending levels.***********************************/void listInv(int widgets, list<pendingItem> &pendingList);/************************************* Function: recvShip()** Description: Recieves a shipment.** Asking for amount, and customer,** fills pending, returns unneeded.***********************************/void recvShip(int &accepted, int &pending, int &sent, int &widgets, int &returned, list<pendingItem> &pendingList);/************************************* Function: request()** Description: Take and fill to ability** a customers request, add rest to pending***********************************/void request(list<pendingItem> &pendingList, int &sent, int &widgets, int &maxpending, int &pending);/************************************* Function: cmdLoop()** Description: Run every command loop,** prints out if the user is low on stock.***********************************/void cmdLoop(int widgets);/************************************* Function: quit()** Description: Exit program. Print out** final values.***********************************/void quit(int accepted, int returned, int sent, int maxpending, int widgets, list<pendingItem> &pendingList);/************************************* Function: getPosInt()** Description: Gets a users input,** only accepts positive integers.***********************************/int getPosInt(string q);/************************************* Function: printPending()** Description: Prints the current list** of pending transactions.***********************************/void printPending(list<pendingItem> &pendingList);/************************************* Function: getString()** Description: Gets a string from** the user***********************************/string getString(string q);int main() { // Initialize variables with 0 values. int widgets = 0; int accepted = 0; int returned = 0; int sent = 0; int maxpending = 0; int pending = 0; // Create the list for pending items. list<pendingItem> pendingList; // Draw the help menu drawMenu(); // Loop through the commands until getCmd returns false (Quit) while (getCmdAndParse(widgets, accepted, returned, sent, maxpending, pending, pendingList)) cmdLoop(widgets); return 0;}/************************************* Function: drawMenu()** Description: Draws the help menu.***********************************/void drawMenu() { cout << string(38, '-') << endl; cout << "Choose from following commands:\n"; cout << cList << " --- list the current inventory level;\n"; cout << cReq << " --- handle a request from the customer;\n"; cout << cShip << " --- handle a shipment from the supplier;\n"; cout << cQuit << " --- terminate the program;\n"; cout << cHelp << " --- display this help message.\n"; cout << string(38, '-') << endl;}/************************************* Function: getCmdAndParse() (Happy?)** Description: Takes users input,** calls whichever function they requested.***********************************/bool getCmdAndParse(int &widgets, int &accepted, int &returned, int &sent, int &maxpending, int &pending, list<pendingItem> &pendingList) { string tmp = getString("\nEnter your choice: "); char cmd = tmp[0]; switch (toupper(cmd)) { case cList: // Call list inv function listInv(widgets, pendingList); break; case cReq: request(pendingList, sent, widgets, maxpending, pending); // Call request function break; case cShip: // Call shipment function recvShip(accepted, pending, sent, widgets, returned, pendingList); break; case cHelp: // Draw the menu drawMenu(); break; case cQuit: quit (accepted, returned, sent, maxpending, widgets, pendingList); // Call quit status function return false; break; default: cout << "--- Invalid command.\n"; break; } return true;}/************************************* Function: listInv()** Description: Prints inventory** and pending levels.***********************************/void listInv(int widgets, list<pendingItem> &pendingList) { cout << "--- Number of widgets in inventory: " << widgets << endl; printPending(pendingList);}/************************************* Function: recvShip()** Description: Recieves a shipment.** Asking for amount, and customer,** fills pending, returns unneeded.***********************************/void recvShip(int &accepted, int &pending, int &sent, int &widgets, int &returned, list<pendingItem> &pendingList) { int amt; amt = getPosInt("Enter the shipment amount: "); accepted += amt; // If there is a pending list, make sure to fill it. if (pendingList.size() > 0) { // Create an iterator to the first element. No need to increase it. list<pendingItem>::iterator iter = pendingList.begin(); while (pendingList.size() > 0) { // Loop through, removing pending items while we have the widgets. if (amt >= iter->pending) { cout << "--- " << iter->pending << " widgets have been sent to " << iter->customer << ".\n"; sent += iter->pending; amt -= iter->pending; pending -= iter->pending; iter = pendingList.erase(iter); } else if (amt > 0) { // If we can partially fill an order, do it. cout << "--- " << amt << " widgets have been sent to " << iter->customer << ".\n"; iter->pending -= amt; pending -= pending; sent += amt; amt = 0; break; } else { break; } } } // Once done pending list, check if there's anything left to recieve if (amt > 0) { // See if it will fill up the inventory or not if (widgets + amt <= maxWidgets) { cout << "--- " << amt << " widgets have been stored.\n"; widgets += amt; } else { // Figure out how much to decline int dec = amt - (maxWidgets - widgets); returned += dec; accepted -= dec; amt -= dec; widgets += amt; if (amt > 0) cout << "--- " << amt << " widgets have been stored.\n"; cout << "--- " << dec << " widgets have been sent " << "back due to lack of storage space.\n"; } }}/************************************* Function: request()** Description: Take and fill to ability** a customers request, add rest to pending***********************************/void request(list<pendingItem> &pendingList, int &sent, int &widgets, int &maxpending, int &pending) { int amt; string cust; // Get customer name and amount. cust = getString("Enter the name of the customer: "); amt = getPosInt("Enter the request amount: "); if (amt <= widgets) { // There's enough widgets to fill order, do so. widgets -= amt; sent += amt; cout << "--- " << amt << " widgets have been sent to " << cust << ".\n"; } else { if (widgets > 0) { // If there's widgets, fill request to ability. sent += widgets; cout << "--- " << widgets << " widgets have been sent to " << cust << ".\n"; amt -= widgets; widgets = 0; } // Add unfilled to a new pendingItem. Add that to pendingList pendingItem *pend = new pendingItem; pend->customer = cust; pend->pending = amt; pendingList.push_back(*pend); pending += amt; if (pending > maxpending) maxpending = pending; cout << "--- " << amt << " widgets requested by " << cust << " have been entered into a pending list.\n"; }}/************************************* Function: quit()** Description: Exit program. Print out** final values.***********************************/void quit(int accepted, int returned, int sent, int maxpending, int widgets, list<pendingItem> &pendingList) { // Print out the list of pending items. printPending(pendingList); // Print out other stats. cout << endl << "==== Statistics ====\n\n"; cout << "Widgets accepted from supplier:" << setw(8) << accepted << endl; cout << "Widgets returned to supplier :" << setw(8) << returned << endl; cout << "Widgets sent to customers :" << setw(8) << sent << endl; cout << "Maximum widgets pending :" << setw(8) << maxpending << endl; cout << "Number of widgets in inventory:" << setw(8) << widgets << "\n\n"; cout << "==== End of run ====" << endl; // Clear the pending list and free the memory. pendingList.clear(); delete(&pendingList);}/************************************* Function: getPosInt()** Description: Gets a users input,** only accepts positive integers.***********************************/int getPosInt(string q) { int amt = 0; // Loop until a valid answer while (cout << q) { cin >> amt; // If there is something wrong, clear cin for proper useage. if (cin.fail()) { cin.clear(); cin.ignore(numeric_limits<streamsize>::max(),'\n'); amt = 0; } if (amt <= 0) cout << "The amount must be a positive number.\n"; else break; } // Clear cin so that getline doesn't complain cin.ignore(numeric_limits<streamsize>::max(),'\n'); return amt;}/************************************* Function: cmdLoop()** Description: Run every command loop,** prints out if the user is low on stock.***********************************/void cmdLoop(int widgets) { // If inventory is too low, print out a warning. if (widgets < minWarning) { cout << "\n!!! Warning! The current inventory level is too low."; cout << "\n!!! Order a new shipment ASAP.\n\n"; }}/************************************* Function: printPending()** Description: Prints the current list** of pending transactions.***********************************/void printPending(list<pendingItem> &pendingList) { cout << "--------------------" << endl; // If there is a pending list, print it. if (pendingList.size() > 0) { cout << "--- Number of requests pending:" << setw(11) << pendingList.size() << endl; // Loop from the beginning to the end of the pending list and print. list<pendingItem>::const_iterator iter; for (iter = pendingList.begin(); iter != pendingList.end(); iter++) { cout << "--- " << iter->pending; cout << " widgets need to be sent to "; cout << iter->customer << ".\n"; } } else // Else, print that there is none. cout << "--- No pending requests.\n"; cout << "--------------------" << endl;}/************************************* Function: getString()** Description: Gets a string from** the user***********************************/string getString(string q) { string a; cout << q; getline( cin, a ); return a;}