Search code examples
c++loopsc++11counteraccumulator

Saving each iteration of an accumulator?


(Yes this WAS homework, but already completed, I'm just trying to improve it now for practice)

This is basically a sales calculator, that allows you to have multiple inputs for sales items, then displays the total, sales tax, and grand total.

The modification I'm trying to make, is that I want to be able to SAVE the cost of each number of items in a variable, without them overlapping memory, and then be able to call them above the grand total, so you can see what each item was worth.

===========================================================================

//importing libraries for cin and cout, as well as setw() and setprecision()
#include <iostream>
#include <iomanip>
using namespace std; //sets all code to standard syntax

int main(){ //initializes the main function

    //initializing variables
    char answer = ' ';
    int saleItems = 0;
    double saleTax = 0.0;
    double grandTotal = 0.0;
    double itemValue = 0.0;
    double titemValue = 0.0;
    double taxPerc = 0.0;

    //begins a post-test loop
    do {
        titemValue = 0.0; //makes sure the accumulator resets WITHIN the loop

        //prompts for sale items amount
        cout << "How many sales items do you have? : ";
        cin >> saleItems;

        //creates a loop that displays the prompt for each iteration of saleItems
        for (int x = 1; x <= saleItems; x += 1){
            cout << "Enter in the value of sales item " << x << " : $";
            cin >> itemValue;
            titemValue += itemValue; //accumulator for adding up the iterated values
        }

        //prompts the user to enter a sales percentage
        cout << endl << endl;
        cout << "Enter in the sales tax percentage(Enter 10 for 10%): ";
        cin >> taxPerc;
        cout << endl << endl;

        //processes the variables after taxPerc has been given
        saleTax = titemValue * (taxPerc / 100);
        grandTotal = titemValue + saleTax;

        //sets decimal precision to 2 places
        cout << fixed << setprecision(2);

        //displays receipt with the calculated and input values
        cout << "********************************************" << endl;
        cout << "********  S A L E S  R E C E I P T  ********" << endl;
        cout << "********************************************" << endl;
        cout << "**                                        **" << endl;
        cout << "**                                        **" << endl;
        cout << "**                                        **" << endl;
        cout << "**                                        **" << endl;
        cout << "**  Total Sales            $" << setw(9) << titemValue << "     **" << endl;
        cout << "**  Sales Tax              $" << setw(9) << saleTax << "     **" << endl;
        cout << "**                          ----------    **" << endl;
        cout << "**  Grand Total            $" << setw(9) << grandTotal << "     **" << endl;
        cout << "**                                        **" << endl;
        cout << "**                                        **" << endl;
        cout << "********************************************" << endl << endl << endl;

        //prompts user to begin loop again
        cout << "Do you want to run this program again? (Y/N):";
        cin >> answer;
        answer = toupper(answer);
        cout << endl << endl;

        } while (answer == 'Y');

===========================================================================

So, essentially, I need to be able to save each itemValue to multiple different values without the loop repeating itself, and just replacing them, and I can't really see how I can do that considering the accumulator will just keep looping, and adding up the itemValue values.


Solution

  • Here is one way to use an simple array to store the item values.

    Declare an array at the top. Note: you will have to give it a fixed size. There are ways to have a variable size, but they get more complex (such as vectors). It is better to specify the size using a constant, rather than a hard coded number, as you will need the constant later.

    const int maxSaleItems = 100;
    double itemValues[maxSaleItems];
    

    After you have asked the user for the number of items, max sure they haven't entered a number that is too big.

        cout << "How many sales items do you have? : ";
        cin >> saleItems;
        if (saleItems > maxSaleItems) {
            cout << "Sorry, I can only handle " << maxSaleItems << " items.";
            continue;
        }
    

    Inside the loop where you are inputting the item values, save the item value to the array:

            cout << "Enter in the value of sales item " << x << " : $";
            cin >> itemValue;
            titemValue += itemValue; //accumulator for adding up the iterated values
            itemValues[x - 1] = itemValue;
    

    Note the x-1 in the array access - arrays are 0 based (i.e. their index starts from 0). Normally I would loop x from 0 to < saleItems, but I didn't want to change your existing loop.

    When printing the receipt, add a loop which prints out all the values (you will need to add formatting):

        cout << "**                                        **" << endl;
        for (int x = 1; x <= saleItems; x += 1){
           cout << "** Item " << x << " $" << itemValues[x-1] << "   **" <<endl;
        }
        cout << "**                                        **" << endl;
    

    As I said in the comments, using std::vector would be better, but if you aren't up to that yet, arrays will do.

    Edit: Simple vector example. To add vectors you need to include the appropriate header:

    #include <vector>
    

    No need for maxSaleItems any more, as vectors can grow. Declare the vector variable. The <double> makes it a vector that contains double values:

    std::vector<double> itemValues;
    

    Inside the loop, instead of setting the array value for the new item by location, just add it to the end of the vector using push_back.

        cout << "Enter in the value of sales item " << x << " : $";
        cin >> itemValue;
        titemValue += itemValue; //accumulator for adding up the iterated values
        itemValues.push_back(itemValue);
    

    The printing receipt code, can be left exactly as it was for the array version, as you can access vectors like arrays:

    cout << "**                                        **" << endl;
    for (int x = 1; x <= saleItems; x += 1){
       cout << "** Item " << x << " $" << itemValues[x-1] << "   **" <<endl;
    }
    cout << "**                                        **" << endl;
    

    There are other changes you could do to make the vector version simpler, but I wanted to change as little as possible.