Thread: First program, input welcome!

  1. #16
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Elysia View Post
    I believe signed overflow/underflow is implementation defined because not all hardware uses two's complement.
    It's actually undefined. (I'd have to check, but don't believe that changed in C++11).
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  2. #17
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by jim_0
    I didn't say it wasn't implementation defined.
    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".

    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.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #18
    Registered User
    Join Date
    Nov 2013
    Posts
    107
    Quote Originally Posted by laserlight View Post
    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".

    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.
    Sorry I see what you mean about the byte size, I just took a 4 bit byte as an example, you can other sizes but the standard is 8 bits nowadays.

  4. #19
    Registered User setleaf's Avatar
    Join Date
    Dec 2014
    Location
    Virginia/USA
    Posts
    47
    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();
    }

  5. #20
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Use iteration instead of recursion for your menu and menuloop functions.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #21
    Registered User setleaf's Avatar
    Join Date
    Dec 2014
    Location
    Virginia/USA
    Posts
    47
    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(); }

  7. #22
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    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?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #23
    Registered User setleaf's Avatar
    Join Date
    Dec 2014
    Location
    Virginia/USA
    Posts
    47
    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.

  9. #24
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by setleaf View Post
    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.
    Yep, that pretty much sums it up.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #25
    Registered User setleaf's Avatar
    Join Date
    Dec 2014
    Location
    Virginia/USA
    Posts
    47
    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;
            }
        }
    }

  11. #26
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yeah, but this part isn't right:
    >>while (selection != 1, 2, 3, 4)
    The comma operator evaluates side effects and returns the last result (i.e. 4). That's not what you want. You have be explicit:
    while (selection != 1 && selection != 2, ...)
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #27
    Registered User setleaf's Avatar
    Join Date
    Dec 2014
    Location
    Virginia/USA
    Posts
    47
    Ah, I was in a hurry from my newfound knowledge and overlooked that.

    Any other tips and comments are welcome!

  13. #28
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Not quite. For starters, this is wrong:
    Code:
    selection != 1, 2, 3, 4
    If you really want to compare selection with 1, 2, 3 and 4, then you should write:
    Code:
    selection != 1 && selection != 2 && selection != 3 && selection != 4
    But you will already be comparing in the switch, so I suggest:
    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");
    }
    In weeklytax, dailytips, taxlog and tiplog, you will then remove the call to menuloop, which no longer exists.

    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.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  14. #29
    Registered User setleaf's Avatar
    Join Date
    Dec 2014
    Location
    Virginia/USA
    Posts
    47
    Wow, great advice laserlight! Looks like I have some more coding to do.

  15. #30
    Registered User setleaf's Avatar
    Join Date
    Dec 2014
    Location
    Virginia/USA
    Posts
    47
    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:
    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;
    }
    Thanks for all the help everyone! Looking back at my initial code, I think its a lot more readable and efficient now.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 6
    Last Post: 07-14-2012, 09:43 AM
  2. getting input from another program
    By adr in forum C++ Programming
    Replies: 6
    Last Post: 03-04-2006, 03:29 AM
  3. C program won't allow input
    By caroundw5h in forum C Programming
    Replies: 1
    Last Post: 11-03-2003, 06:59 PM
  4. Other than cin, how can a get a program to take input?
    By deathstryke in forum C++ Programming
    Replies: 15
    Last Post: 01-30-2003, 02:56 PM
  5. Any input on this program
    By Kyoto Oshiro in forum C++ Programming
    Replies: 6
    Last Post: 03-02-2002, 01:08 PM