#include #include #include #include #include #include #include #include "BoundedStack.h" #include "BoundedStackA.h" #include "BoundedStackB.h" using namespace std; istream *isr; bool echoinput; bool endOfInput=false; string* GeneralQuestion(string* prompt) { string response; string *answer = &response; bool done = false; if (prompt) cout << *prompt; while (!done) { getline(*isr, response); if ((*isr).eof()) { // must be EOF if (echoinput) { // switch to keyboard input isr = &cin; echoinput=false; } else { cout << "unexpected end of input reached.\n"; endOfInput = true; answer = NULL; done=true; } } else { // successful so far if (echoinput) cout << response << "\n"; if ((response).length()>0) done=true; } } if (answer) { answer = new string(response); } return(answer); } bool valid(BoundedStack *bs) { if (bs==NULL) { cout << "The history has not yet been properly initialized.\n"; return(false); } else { return(true); } } int main(int argc, const char* argv[]) { string MENU = "Valid commands include:\n(A) create or reinitialize with BoundedStackA.\n(B) create or reinitialize with BoundedStackB.\n(S) call size.\n(E) call isEmpty.\n(U) call Push.\n(P) call Pop\n(T) call Top\n(Q) Quit."; filebuf fb; bool quit = false; int value; int i; int command=1; string *response; string answer; char choice; BoundedStack *BS = NULL; // choose between keyboard input or mock-keyboard file input echoinput = false; isr = &cin; if (argc>1) { fb.open(argv[1],ios::in); if (fb.is_open()) { isr = new istream(&fb); echoinput= true; } else { cout << "Input file '" << argv[1] << "' not found.\n"; cout << "Defaulting to keyboard input.\n\n"; } } // is there a limit on the number of lines to read? int LIMIT = -1; if (argc>2) { LIMIT = atoi(argv[2]); if (LIMIT < 1) { LIMIT = -1; cout << "Second argument (" << argv[2] << ") ignored.\n\n"; } } cout << MENU << "\n"; do { char temp[50]; sprintf(temp,"\nCommand #%i> ",command); response = GeneralQuestion(new string(temp)); command++; if (response==NULL) { choice = 'q'; } else { choice = (*response)[0]; if (response) delete response; } switch (choice) { case 'a': case 'A': case 'b': case 'B': response = GeneralQuestion(new string("Enter a capacity for the history: ")); if (!response) { cout << "Invalid capacity. Aborting command.\n"; } else { value = atoi((*response).c_str()); delete response; if (value<1) { cout << "Invalid capacity. Aborting command.\n"; } else { if ((choice=='a') || (choice=='A')) { BS = new BoundedStackA(value); cout << "BoundedStackA constructor called with capacity " << value << "\n"; } else { BS = new BoundedStackB(value); cout << "BoundedStackB constructor called with capacity " << value << "\n"; } } } break; case 's': case 'S': if (valid(BS)) { i = (*BS).size(); cout << "size( ) returned " << i << "\n"; } break; case 'e': case 'E': if (valid(BS)) { bool s = (*BS).isEmpty(); cout << "isEmpty( ) returned " << (s ? "true" : "false") << "\n"; } break; case 'u': case 'U': if (valid(BS)) { response = GeneralQuestion(new string("Enter item to push: ")); if (!response) { cout << "Error in reading item. Aborting command.\n"; } else { (*BS).push((*response)); delete response; } } break; case 'p': case 'P': if (valid(BS)) { try { answer = (*BS).pop(); cout << "pop( ) returned " << answer << "\n"; } catch (BoundedStackEmptyException e) { cout << "pop( ) threw BoundedStackEmptyException\n"; } } break; case 't': case 'T': if (valid(BS)) { try { answer = (*BS).top(); cout << "top( ) returned " << answer << "\n"; } catch (BoundedStackEmptyException e) { cout << "top( ) threw BoundedStackEmptyException\n"; } } break; case 'q': case 'Q': quit = true; break; default: cout << "Unrecognized option: " << choice << "\n"; cout << MENU << "\n"; } } while (!quit && (LIMIT<0 || command