Well, you did say that "If you go over the max value then you get overflow and in C++ wrap around", but strictly speaking if the destination is a signed integer, then going over the max value results in an implementation defined value, which may or may not have anything to do with "wrap around".Originally Posted by jim_0
Likewise, strictly speaking a byte is at least 8 bits, not necessarily exactly 8 bits, though outside of its usage in standard C++ the term does refer to an 8-bit byte these days unless otherwise specified.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
Here is my complete code for the program as of now. It's all working as I intend, but I'm sure there are things I can improve.
Feel free to comment.
Code:#include <iostream> #include <string> #include <fstream> using namespace std; void menu(); void menuloop() { string sel; // Variable to return to menu cout<< "If you would like to return to the main menu, enter 'y'.\n"; cout<< "Otherwise you may exit the program.\n"; cout<< ": "; cin>> sel; cout<< "\n"; if (sel == "y") menu(); else menuloop(); } void weeklytax() // Code to run when 'Calculate Weekly Tax' is selected. { string sel; // Variable to ensure user entered the right information string week; // The week the taxes are being calculated for double pay; // User's paycheck double statetax = 12.50; // Weekly state tax amount double fedsub = 163.0; // Amount to subtract before multiplying by fedmult double fedmult = .10; // Federal income tax of 10% double tax; // Actual amount of taxes int taxrecord; // Variable to hold amount of tax entries while (sel != "y") // Repeats until the user enters 'y' that the info is correct { cout<< "Please enter the last day of your most recent pay period (mm/dd/yy): "; cin>> week; cout<< "\n"; cout<< "Please enter your paycheck amount for "<<week<<": $"; cin>> pay; cout<< "\n"; cout<< "Please review your information.\n\n"; cout<< "For "<<week<<", you made $"<<pay<<". Is this correct?\n\n"; cout<< "Enter 'y' for yes, or 'n' for no: "; cin>> sel; cout<< "\n"; } tax = (((pay - fedsub) * fedmult) + statetax); ofstream taxwrite; taxwrite.open("weeklytax.dat", ios::app); //taxwrite<< week <<"\n"; taxwrite<< tax<<"\n"; taxwrite.close(); ifstream taxget; taxget.open("taxrecord.dat", ios::in); taxget>> taxrecord; taxrecord += 1; taxget.close(); ofstream taxgo; taxgo.open("taxrecord.dat", ios::out | ios::trunc); taxgo<< taxrecord; taxgo.close(); cout<<"Your weekly tax for "<<week<<" is $"<<tax<<", and has been logged.\n\n"; menuloop(); } void dailytips() { int tips; int tiprecord; string sel; // First selection, ensures tip info is correct while (sel != "y") // Repeats until the user enters 'y' that the info is correct { cout<< "Please enter the amount of tips you received today: $"; cin>> tips; cout<< "\n"; cout<< "Please review your information.\n\n"; cout<< "You made $"<<tips<<" in tips today. Is this correct?\n\n"; cout<< "Enter 'y' for yes, or 'n' for no: "; cin>> sel; cout<< "\n"; } ofstream tipwrite; tipwrite.open("tipdaily.dat", ios::app); tipwrite<< tips; tipwrite<< "\n"; tipwrite.close(); ifstream tipget; tipget.open("tiprecord.dat", ios::in); tipget>> tiprecord; tiprecord += 1; tipget.close(); ofstream tipgo; tipgo.open("tiprecord.dat", ios::out | ios::trunc); tipgo<< tiprecord; tipgo.close(); cout<<"Your tip amount of $"<<tips<<" has been logged.\n\n"; menuloop(); } void taxlog() { double tax; // Holds first tax entry, and resulting sum double tax2; // Holds every tax after first entry. int taxrecord; // Holds number of tip entries logged from dailytips() ifstream lognum; // lognum.open("taxrecord.dat", ios::in); // Open amount of tax entries logged lognum>> taxrecord; //Record tax entries into taxrecord variable lognum.close(); // Close the file ifstream taxdisplay; taxdisplay.open("weeklytax.dat"); // Open file that contains the monetary tax values for (int i = taxrecord; i > 0; i--) // While i is less than the amount of taxrecord... { taxdisplay>> tax; // Records first tax entry into tax variable for (i = taxrecord - 1; i > 0; i--) // If i is greater than 1.... { taxdisplay>> tax2; // Records second and any following taxes into tax2 tax += tax2; // Adds tax value and tax2 value } } taxdisplay.close(); cout<< "You have "<<taxrecord<<" tax entries.\n"; cout<< "Your taxes owed as of your last paycheck calculate to: $"<<tax<<"\n\n"; menuloop(); } void tiplog() // Displays year to date tips { double tips; // Holds first tip entry, and resulting sum double tips2; // Holds every tip after first entry. int tiprecord; // Holds number of tip entries logged from dailytips() ifstream lognum; // lognum.open("tiprecord.dat", ios::in); // Open amount of tip entries logged lognum>> tiprecord; //Record tip entries into tiprecord variable lognum.close(); // Close the file ifstream tipdisplay; tipdisplay.open("tipdaily.dat"); // Open file that contains the monetary tip values for (int i = tiprecord; i > 0; i--) // While i is less than the amount of tiprecord... { tipdisplay>> tips; // Records first tip entry into tips variable for (i = tiprecord - 1; i > 0; i--) // If i is greater than 1.... { tipdisplay>> tips2; // Records second and any following tips into tips2 tips += tips2; // Adds tips value and tips2 value } } tipdisplay.close(); // Close the file cout<< "You have "<<tiprecord<<" tip entries.\n"; cout<< "Your year to date tips calculate to: $"<<tips<<"\n\n"; menuloop(); } void menu() { int selection; cout<< "1. Calculate Weekly Tax\n"; cout<< "2. Enter Daily Tips\n"; cout<< "3. View Tax Logs\n"; cout<< "4. View Tip Logs\n"; cin>> selection; switch (selection) { case 1: weeklytax(); break; case 2: dailytips(); break; case 3: taxlog(); break; case 4: tiplog(); break; default: cout<< "Invalid selection. Please try again.\n"; menu(); break; } } int main() { cout<< "Nick's Tax and Tip Calculator v1.1\n\n"; menu(); }
Use iteration instead of recursion for your menu and menuloop functions.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
Thanks for the tip laserlight. I haven't actually read anything about recursion or iteration up to this point. From some quick reading online I see that recursion uses up more stack memory, but is easier to read. Iteration is a little harder to read and understand but will make the program more efficient.
As far as how to implement one vs. the other I'm not entirely sure.
Would simply using a while statement instead of an if/else statement classify my functions as Iteration?
Like so:
Code:
void menuloop() { string sel; // Variable to return to menu cout<< "If you would like to return to the main menu, enter 'y'.\n"; cout<< "Otherwise you may exit the program.\n"; cout<< ": "; cin>> sel; cout<< "\n"; while (sel == "y") menu(); while (sel != "y") menuloop(); }
Recursion is a function directly or indirectly calling itself. By indirect I mean function X calling other functions which eventually results in function X being called again.
Iteration is a loop (for, while, do-while).
Iteration is easier to read and understand than recursion. Recursion can be more powerful and flexible, but yes, uses more memory (every local variable and its parameters needs to be allocated again for the new invocation).
So... to test your new knowledge, is your example iteration or recursion?
That breaks it down much better than what google produced Elysia, thank you! So since my menuloop() function recalls itself if the user does not enter "y" it would be classified as recursion, regardless of if i use "if" or "while" statements.
Sooo to change my functions to iteration I would need something like this, right?
Code:void menuloop() { string sel; // Variable to return to menu while (sel != "y") { cout<< "If you would like to return to the main menu, enter 'y'.\n"; cout<< "Otherwise you may exit the program.\n"; cout<< ": "; cin>> sel; cout<< "\n"; } while (sel == "y") menu(); } void menu() { int selection; while (selection != 1, 2, 3, 4) { cout<< "1. Calculate Weekly Tax\n"; cout<< "2. Enter Daily Tips\n"; cout<< "3. View Tax Logs\n"; cout<< "4. View Tip Logs\n"; cin>> selection; switch (selection) { case 1: weeklytax(); break; case 2: dailytips(); break; case 3: taxlog(); break; case 4: tiplog(); break; } } }
Ah, I was in a hurry from my newfound knowledge and overlooked that.
Any other tips and comments are welcome!
Not quite. For starters, this is wrong:
If you really want to compare selection with 1, 2, 3 and 4, then you should write:Code:selection != 1, 2, 3, 4
But you will already be comparing in the switch, so I suggest:Code:selection != 1 && selection != 2 && selection != 3 && selection != 4
In weeklytax, dailytips, taxlog and tiplog, you will then remove the call to menuloop, which no longer exists.Code:void menu() { bool valid_selection = true; do { cout << "1. Calculate Weekly Tax\n"; cout << "2. Enter Daily Tips\n"; cout << "3. View Tax Logs\n"; cout << "4. View Tip Logs\n"; int selection; cin >> selection; switch (selection) { case 1: weeklytax(); break; case 2: dailytips(); break; case 3: taxlog(); break; case 4: tiplog(); break; default: valid_selection = false; cout << "Invalid selection\n"; } } while (!valid_selection); } int main() { string sel; do { menu(); cout << "If you would like to return to the main menu, enter 'y'.\n"; cout << "Otherwise you may exit the program.\n"; cout << ": "; cin >> sel; cout << "\n"; } while (sel == "y"); }
This way, notice the flow of control: it starts in the main function, goes to menu, then goes to say, taxlog, then when taxlog ends, it resumes where it left off in menu, then when menu ends, it resumes where it left off in main, after which it may (or may not) enter a new call of the menu function, etc.
If you kept the menuloop call in taxlog, then you would still have recursion: the flow of control would start in the main function, goes to menu, goes to taxlog, then menuloop, then menu, etc.
EDIT:
Incidentally, if you really want to write menu to do one thing and do it well, you should separate out the part that calls the other functions. Rather, have menu print the menu and process the input, but not trigger the action. Instead, menu could return the valid input. The main function will then take the return value of menu and use it to call the appropriate function. Then, you could move the code that asks the user if he/she would like to return to the main menu or exit into another function which the main function can then call.
Last edited by laserlight; 01-04-2015 at 12:15 PM.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
Wow, great advice laserlight! Looks like I have some more coding to do.
After a lot of trial and error I finally got my program to contain no recursion. My main() passes a reference into menu() to hold the choice the user selects, then main decides which code to execute:
Thanks for all the help everyone! Looking back at my initial code, I think its a lot more readable and efficient now.Code:void menu(int &choice) { cout<< "\t\t************************************************\n"; cout<< "\t\t*\t 1. Calculate Weekly Tax *\n"; cout<< "\t\t*\t 2. Enter Daily Tips *\n"; cout<< "\t\t*\t 3. View Tax Logs *\n"; cout<< "\t\t*\t 4. View Tip Logs *\n"; cout<< "\t\t************************************************\n"; cout<< "Please enter your selection: "; cin>> choice; cout<< "\n\n"; } int main() { bool isUsing = USING; while(isUsing) { string sel = ""; int choice = 0; menu(choice); switch (choice) { case 1: weeklytax(); break; case 2: dailytips(); break; case 3: taxlog(); break; case 4: tiplog(); break; default: cout << "Invalid Selection.\n\n"; } cout << "If you would like to return to the main menu, enter 'y': "; cin >> sel; if (sel == "y") isUsing = USING; else isUsing = QUIT; } return 0; }