C++ convert my linked list class to structured program

profilebunnie666
lab_6.zip

LISTINGS.txt

345678 116900 0 80513-2918 Metro Brokers 432395 150743 1 80512-2771 City Realty 353455 342522 2 34534-3454 Upper East 999999 99999 2 92130-1312 This Test 555555 555555 0 77777-7777 Final Test

CHANGES.txt

432395 -25000 353455 -2500 221111 -1000 345678 +5000

HodellAssn#6.cpp

//************************************************************************* #include <iostream> #include <fstream> #include <string> #include <iomanip> #include <cctype> using namespace std; // Global structure definition enum availability { AVAILABLE, CONTRACT, SOLD }; struct propertiesRec { int mlsNum; double price; availability status; string zipCode; string realtor; }; //FUNCTION PROTOTYPES SECTION - //Previous Lab#4 functions with linked list mods void IntroProgram (); char MenuOne(); char UserMenuChoices (); void Add_New_Listing (); int Existing_Listings (); int Get_Validate_MLS_Input (); double Get_Validate_Price_Input (); availability Get_Status_Entry(); string Status_Enum_Text ( int ); string Get_Validate_ZipCode_Input (); string Get_Validate_Realtor_Input (); int CountIntegers( int ); void Display_MLS_Numbers (); bool Does_File_Exist(const char *fileName); //Class Definition - New Lab#6 Functions class node { propertiesRec Xdata; node *next; public: //Default constructor used to initialize variable with values node() { next=0; } //Constructor with parameters node ( propertiesRec varibable ) { Xdata = varibable; next = 0; } void put_next ( node *n ) { next = n; } node *Get_Next ( ) { return next; } int Get_MLS ( ) { return Xdata.mlsNum; } double Get_AskingPrice ( ) { return Xdata.price; } int Get_ListingStatus ( ) { return Xdata.status; } string Get_ZipCode() { return Xdata.zipCode; } string Get_Realtor() { return Xdata.realtor; } void SetAskingPrice( double ); void Append_List( propertiesRec ); void Remove_Node(); void DisplayListings(); void WriteToFile(); void ChangeAskingPrice(); //Declaring two nodes: header and 'n' initialized to 0. } *header=0, *n=0; //Input data constants const int MAX_REALTY_NAME = 15; const int MAX_ZIPCODE = 10; const char Y_UPPERCASE = 'Y'; const char N_UPPERCASE = 'N'; const char ADD_LISTING = 'A'; const char REMOVE_LISTING = 'R'; const char DISPLAY_ALL = 'D'; const char CHANGE_ASKING_PRICE = 'C'; const char EXIT_PROGRAM = 'E'; //************************************************************************* // FUNCTION: main // DESCRIPTION: Main function will call various functions to read, input, // calculate and display per account the phone usage totals // CALLS TO: // IntroProgram //************************************************************************* int main() { // variables int count; char additional; propertiesRec listings; bool exit=false; n = new node(); // Begin Program execution IntroProgram (); additional = MenuOne(); if (additional == Y_UPPERCASE) { Existing_Listings(); } else { Add_New_Listing (); } while( !exit ) { additional = UserMenuChoices (); switch ( additional ) { case DISPLAY_ALL: if ( header == 0 ) { cout << "No existing data - Please Add data" << endl; Add_New_Listing (); } else { n->DisplayListings(); } break; case ADD_LISTING: { Add_New_Listing(); } break; case REMOVE_LISTING: { n->Remove_Node(); } break; case CHANGE_ASKING_PRICE: { n->ChangeAskingPrice(); } break; case EXIT_PROGRAM: { n->WriteToFile(); exit = true; } } } return 0; } //************************************************************************* // FUNCTION: Program Introduction // DESCRIPTION: Introduce user to Reality Listing Program // INPUT: None // OUTPUT: Display a introduction to the user of the program. //************************************************************************* void IntroProgram (void) { cout << endl; cout << "Welcome to the Realtor's Association MLS Listing(s) Program" << endl; cout << endl; } //************************************************************************* // FUNCTION: Menu One // DESCRIPTION: First menu that the user can use to make a choice. // INPUT: User input and error correction // OUTPUT: Returns an answer to the main function. //************************************************************************* char MenuOne() { char answer; cout << endl; cout << "Load existing data from file (Y/N) " << endl;; cout << "Y - Existing MLS Listing(s)" << endl; cout << "N - Enter New Listing(s)" << endl; cout << "Enter choice: "; do { cin >> answer; answer = toupper(answer); if (answer != Y_UPPERCASE && answer != N_UPPERCASE) { cout << "invalid choice: re-enter\n"; } } while (answer != Y_UPPERCASE && answer != N_UPPERCASE); return answer; } //************************************************************************* // FUNCTION: Existing Records // DESCRIPTION: Reads the LISTINGS.txt file into an linked list // INPUT: inputFile (LISTINGS.txt) are called for read from this // function, if there is no txt and error will be screened // and the user can either exit or add new data to the new // linked list. // OUTPUT: A return value countRec records and adds up the number of // records read into the array-struct. //************************************************************************* int Existing_Listings() { int availabilityInt; char userAns; char filename[20]; cout << "Enter a filename: "; cin >> filename; struct propertiesRec listings; ifstream inputFile(filename); if (!inputFile) { cout<< "INPUT FILE DOES NOT EXISTS." << endl; } else { while ( !inputFile ) { cout << "No Existing file data available or Input file did not open." << endl; cout << "Would you like to (A)dd new listings or (E)xit?" << endl; cin >> userAns; userAns = toupper (userAns); if ( userAns == 'A' ) { Add_New_Listing(); return 0; } if ( userAns == 'E' ) { return 1; } } while ( inputFile >> listings.mlsNum ) { inputFile >> listings.price >> availabilityInt >> listings.zipCode; getline ( inputFile, listings.realtor); listings.status = static_cast<availability>(availabilityInt); n->Append_List(listings); } } inputFile.close(); } //************************************************************************* // FUNCTION: (A)dd Records // DESCRIPTION: This function takes user input via keyboard and copies it // per member into a array-struct record. // INPUT: Take use input and also countRec (# of actual records at // that moment. It also calls verification functions to verify // the data being entered. // OUTPUT: Adds a new record the array-struct and asks if they would // like to continue or stop. //************************************************************************* void Add_New_Listing () { char more; do { propertiesRec listings; listings.mlsNum = Get_Validate_MLS_Input(); listings.price = Get_Validate_Price_Input(); listings.status = Get_Status_Entry(); listings.zipCode = Get_Validate_ZipCode_Input (); listings.realtor = Get_Validate_Realtor_Input (); n->Append_List( listings ); // Appends the linked list cout << endl; cout << "More Listing(s) to add (Y)es or (N)o?"; cin >> more; } while ( toupper(more) != N_UPPERCASE ); } //************************************************************************* // FUNCTION: Display Listings // DESCRIPTION: // INPUT: // OUTPUT: // //************************************************************************* void node::DisplayListings() { // Header Display cout << setw(15) << "Asking" << setw(11) << "Listing" << endl; cout << "MLS" << setw(11) << "Price" << setw(11) << "Status" << setw(13) << "zipcode" << setw(13) << "Realtor" << endl; cout << "------ " <<"------- " << "--------- " << "---------- " << "------------ " << endl; node *q; for( q=header; q!= 0; q= q->Get_Next() ) { cout << q->Get_MLS() << setw(10) << q->Get_AskingPrice() << setw(12); string status = Status_Enum_Text ( q->Get_ListingStatus() ); if ( q->Get_ListingStatus() == 0 ) { cout << setw(12) << status; cout << setw(13) << q->Get_ZipCode(); cout << " " << left << setw(10) << q->Get_Realtor() << right << endl; } if ( q->Get_ListingStatus() == 1 ) { cout << setw(11) << status; cout << setw(14) << q->Get_ZipCode(); cout << " " << left << q->Get_Realtor() << right << endl; } if ( q->Get_ListingStatus() == 2 ) { cout << setw(7) << status; cout << setw(18) << q->Get_ZipCode(); cout << " " << left << q->Get_Realtor() << right << endl; } } } //************************************************************************* // FUNCTION: User Menu Choices // DESCRIPTION: This is the central user menu where they can make choices. // INPUT: This function takes no input, but does error check what the // user enters. // OUTPUT: A menu with all the major takes that this program can accomplish. //************************************************************************* char UserMenuChoices () { char answer; cout << endl; cout << "User Menu Choices:" << endl; cout << "------------------" << endl; cout << "D - Display All" << endl; cout << "A - Add Listing(s)" << endl; cout << "R - Remove Listing(s)" << endl; cout << "C - Change Asking Price" << endl; cout << "E - Exit Program" << endl; cout << "Please enter your choice "; cout << endl; do { cin >> answer; answer = toupper(answer); if ( answer != DISPLAY_ALL && answer != ADD_LISTING && answer != REMOVE_LISTING && answer!= CHANGE_ASKING_PRICE && answer != EXIT_PROGRAM ) { cout << "invalid choice: re-enter" << endl; } } while ( answer != DISPLAY_ALL && answer != ADD_LISTING && answer != REMOVE_LISTING && answer!= CHANGE_ASKING_PRICE && answer != EXIT_PROGRAM ); return answer; } //************************************************************************* // FUNCTION: Append_List // DESCRIPTION: XXXXXXXXXXXXXXXXXXXXXXX // INPUT: XXXXXXXXXXXXXXXXXXXXXXXXXX // OUTPUT: XXXXXXXXXXXXXXXXXXXXXXXX //************************************************************************* void node::Append_List( propertiesRec Xdata ) { node *q,*t; if( header == 0 ) { header= new node ( Xdata ); } else { q = new node(); q = header; while( q->Get_Next() !=0 ) { q = q->Get_Next(); } t = new node( Xdata ); q->put_next( t ); } } //************************************************************************* // FUNCTION: Remove_Node // DESCRIPTION: XXXXXXXXXXXXXXXXXXXXXXX // INPUT: XXXXXXXXXXXXXXXXXXXXXXXXXX // OUTPUT: XXXXXXXXXXXXXXXXXXXXXXXX //************************************************************************* void node::Remove_Node() { Display_MLS_Numbers(); int mls; cout << "Enter MLS to remove: "; mls = Get_Validate_MLS_Input(); node *q,*r; q = header; // If node to be deleted is the first node if( q->Get_MLS() == mls ) { header = q->Get_Next(); delete q; return; } //if node to be deleted is not the first node r = q; while( q!= 0 ) { if( q->Get_MLS() == mls ) { r->next=q->next; delete q; return; } r = q; q = q->Get_Next(); } cout << "MLS number " << mls << " not Found."; } //************************************************************************* // FUNCTION: WriteToFile // DESCRIPTION: XXXXXXXXXXXXXXXXXXXXXXX // INPUT: XXXXXXXXXXXXXXXXXXXXXXXXXX // OUTPUT: XXXXXXXXXXXXXXXXXXXXXXXX //************************************************************************* void node::WriteToFile() { if ( header == NULL ) // End of list or not populated head node { cout << "No existing data - no data will be saved" << endl; } char ch; bool again= true; cout<<"Do you want to save the listing(y/n): "; cin>>ch; ch=toupper( ch ); if ( ch=='Y' ) { char filename[20]; cout<<"Enter file name to save: "; cin>>filename; do { if ( Does_File_Exist(filename) ) //if file already exists { cout << "this file already exists. Do you want to overwrite it (y/n): "; cin >> ch; ch = toupper( ch ); if ( ch == 'Y' ) { ofstream FileOutput; FileOutput.open( filename ); node *q; for( q= header; q!= 0; q= q->Get_Next() ) { FileOutput << q->Get_MLS() << " " << q->Get_AskingPrice() << " " << q->Get_ListingStatus() << " "; FileOutput << q->Get_ZipCode() << " " << q->Get_Realtor() << endl; } FileOutput.close(); again=false; } else { cout << "Enter another file name to save the listing: "; cin >> filename; } } else //if file does not exists { ofstream FileOutput; FileOutput.open( filename ); node *q; //iterate from header to the end of the linked list for( q=header; q!= 0; q= q->Get_Next() ) { FileOutput << q->Get_MLS() << " " << q->Get_AskingPrice() << " " << q->Get_ListingStatus() << " "; FileOutput << q->Get_ZipCode() << " " << q->Get_Realtor() << endl; } FileOutput.close(); again= false; } } while( again ); } } //************************************************************************* // FUNCTION: SetAskingPrice // DESCRIPTION: XXXXXXXXXXXXXXXXXXXXXXX // INPUT: XXXXXXXXXXXXXXXXXXXXXXXXXX // OUTPUT: XXXXXXXXXXXXXXXXXXXXXXXX //************************************************************************* void node::SetAskingPrice( double newPrice ) { Xdata.price = newPrice; } //************************************************************************* // FUNCTION: ChangeAskingPrice // DESCRIPTION: XXXXXXXXXXXXXXXXXXXXXXX // INPUT: XXXXXXXXXXXXXXXXXXXXXXXXXX // OUTPUT: XXXXXXXXXXXXXXXXXXXXXXXX //************************************************************************* void node::ChangeAskingPrice() { ifstream inputFile; inputFile.open( "CHANGES.TXT" ); if ( !inputFile ) { cout << "ERROR: File 'Changes.txt' does not exists." << endl; return; } int mls; double price; node *q; bool found = false; cout << "MLS number" << setw(20) << "New Asking Price" << endl; cout<<"---------- " << " ----------------" << endl; while ( inputFile >> mls ) { inputFile >> price; for( q= header; q!= 0; q= q->Get_Next() ) { if ( q->Get_MLS() == mls ) { found= true; q->SetAskingPrice( q->Get_AskingPrice()-price ); cout << mls << setw(14) << q->Get_AskingPrice() << endl; } } } inputFile.close(); if ( found == false ) { cout << "No matching MLS number found" << endl; } } //************************************************************************* // FUNCTION: Enter MLS listing // DESCRIPTION: Gets and validates the MLS number from the user // INPUT: User input with error correction. // OUTPUT: Writes data back to add data function. //************************************************************************* int Get_Validate_MLS_Input () { int MAX_MLS_NUMBER = 6; int MIN = 100000; int MAX = 999999; int mlsNum; cout << endl; cout << "Enter MLS number (Between 100000 - 999999)"; cin >> mlsNum; int numIntegers = CountIntegers( mlsNum ); while (cin.fail()) { cin.clear(); cin.ignore(); cout << "not integer" << endl; cin.clear(); cin.ignore(); cin>>mlsNum; } numIntegers = CountIntegers( mlsNum ); do { if ( numIntegers > MAX_MLS_NUMBER ) { cout << endl; cout << "Length of MLS too long - Only 6 Digits." << endl; cin >> mlsNum; numIntegers = CountIntegers( mlsNum ); } } while ( numIntegers > MAX_MLS_NUMBER ) ; while (! ( mlsNum > MIN ) || ( mlsNum > MAX )) { cout << "Invalid Entry - (Between 100000 - 999999)"; cin.clear(); cin.ignore(); cin>>mlsNum; } return mlsNum; } //************************************************************************* // FUNCTION: Enter Price // DESCRIPTION: Gets and validates the price entered by the user. // INPUT: User input with error correction. // OUTPUT: Writes data back to add data function. //************************************************************************* double Get_Validate_Price_Input () { int MAX_Price_Length = 6; int MIN = 1; int MAX = 999999; int price; cout << endl; cout << "Enter Price (Between 1 - 999999)"; cin >> price; int numIntegers = CountIntegers( price ); while ( cin.fail() ) { cin.clear(); cin.ignore(); cout << "not integer" << endl; cin>>price; } numIntegers = CountIntegers( price ); do { if ( numIntegers > MAX_Price_Length ) { cout << endl; cout << "Length of Price too long - Only 6 Digits." << endl; cin >> price; numIntegers = CountIntegers( price ); } } while (( numIntegers > MAX_Price_Length ) && ( cin.fail()) ); return price; } //************************************************************************* // FUNCTION: Count Number of Integers // DESCRIPTION: counts the numbers // INPUT: Enter price function inputs the user data. // OUTPUT: Returns the actual numbers entered by the user to the calling // function. //************************************************************************* int CountIntegers( int number ) { if ( number < 10 ) { return 1; } int countInt = 0; while ( number > 0 ) { number /= 10; countInt++; } return countInt; } //************************************************************************* // FUNCTION: Enter ZipCode // DESCRIPTION: Gets and validates the zipCode number. // INPUT: User input with error correction. // OUTPUT: Writes data back to add data function. //************************************************************************* string Get_Validate_ZipCode_Input () { string zipCode; bool valid = true; do { valid = true; cout << "Enter Zipcode (XXXXX-XXXX)" << endl; cin >> zipCode; if ( zipCode.length() <10 || zipCode.length() > MAX_ZIPCODE ) { cout << "Invalid ZipCode - Zip code length must be 10 " << endl; valid = false; } else if ( zipCode[5] != '-' ) { cout << "Invalid ZipCode - '-' is not at correct position" << endl; valid = false; } else { for ( int counter = 0; counter <= 4; counter++ ) { if ( !isdigit(zipCode[counter]) ) { cout << "Invalid ZipCode - all must be digits" << endl; valid = false; } } for ( int counter = 6; counter <= 9; counter++ ) { if ( !isdigit(zipCode[counter]) ) { cout << "Invalid ZipCode - all must be digits" << endl; valid = false; } } } }while ( valid == false ); return zipCode; } //************************************************************************* // FUNCTION: Enter Realty Company Name // DESCRIPTION: Gets and validates the propertiesRec name // INPUT: User input with error correction. // OUTPUT: Writes data back to add data function. //************************************************************************* string Get_Validate_Realtor_Input () { string propertiesRec; int counter; bool valid = true; do { cout << endl; cout << "Enter propertiesRec Name, only letter(s) and spaces allowed " << endl; cin.ignore(); getline( cin, propertiesRec ); if ( propertiesRec.length() > MAX_REALTY_NAME ) { cout << "Invalid propertiesRec Name" << endl; getline( cin, propertiesRec ); } } while ( propertiesRec.length() > MAX_REALTY_NAME ); // This tests for letters for ( int counter = 0; counter < propertiesRec.length(); counter++ ) { if ( !isalpha(propertiesRec[counter]) && valid == true ) { cout << "Invalid propertiesRec Name" << endl; getline( cin, propertiesRec ); } // This is the first letter Capitializer for (int counter = 0; counter < propertiesRec.length(); counter++) { if ( isalpha(propertiesRec[counter]) && valid == true ) { propertiesRec[counter] = toupper( propertiesRec[counter] ); valid = false; } else if (isspace ( propertiesRec[counter]) ) valid = true; } } return propertiesRec; } //************************************************************************* // FUNCTION: Get Status Entry // DESCRIPTION: Takes user input and enters the status via switch. // INPUT: User input with error correction. // OUTPUT: Outputs the data into the array-struct via add data function. //************************************************************************* availability Get_Status_Entry() { int entry; cout << "Enter the listing's status ( 0 - Available; 1 - Contract, 2 - Sold): "; while ( !(cin >> entry) || entry < 0 || entry > 2 ) { cout << "Invalid listing status, please enter 0 - Available, 1 - Contract, or 2 - Sold." << endl; cout << "Try again: "; cout << endl; } switch (entry) { case 0: return AVAILABLE; case 1: return CONTRACT; case 2: return SOLD; default: break; } } //************************************************************************* // FUNCTION: Status Enum to Text // DESCRIPTION: Converts from cell integer to enumuration for display // INPUT: Is call by the display all function. // OUTPUT: Returns the correct converted enumeration status type. //************************************************************************* string Status_Enum_Text (int status) { switch (status){ case 0: return "AVAILABLE"; case 1: return "CONTRACT"; case 2: return "SOLD"; default: break; } } //********************************************************************* // FUNCTION: Display MLS Numbers // DESCRIPTION: Displays MLS list from the Linked-list. Checks first if // there are any MLS records. // INPUT: Reads the Linked-list // OUTPUT: Outputs to screen a header and list of current MLS#. //********************************************************************** void Display_MLS_Numbers () { node *q; if ( header == NULL ) { cout << "There are no Listings stored." << endl; } else { cout << "MLS#" << endl; cout << "------" << endl; //Work through head node to null node for( q= header; q!= 0; q= q->Get_Next() ) { cout << q->Get_MLS() << endl; } cout << endl; } } //********************************************************************* // FUNCTION: Does_File_Exist // DESCRIPTION: Performs a check on the existence of the user inputed // file name. // INPUT: // OUTPUT: // //********************************************************************** bool Does_File_Exist ( const char *fileName ) { ifstream inputFile( fileName ); bool exists = false; if ( inputFile ) exists= true; return exists; }