0

i have a project for a cs class due late next week and ive got it almost done but i am having a few problems and ive been trying everything and cant get it to work. Our project consists of taking 3 months of 3 customers information and monthly utility charges from an input file, storing all of this in arrays, then calculating subtotals, tax, discount, and total paid then storing this into arrays, and then outputting 1 quarterly receipt for each customer. We have to do this using functions. my main problem is that it is only outputting the first customers receipt and ive double checked my for loop and to me it looks like it should work.

Thanks A lot

heres the output file

             Austin City Office, Texas
                           RECEIPT #59, September28, 2013, 09:00PM

Customer ID: 127654 Name: Jack Jones Address: 2059 Joe Lane, Austin TX, 78646 Phone Number: 512-520-5862

Electricity Charges: $6 Water Charges: $24 Gas Charges: $12

Subtotal: $42 Discount Amount: $0.84 (2% discount since your subtotal is less than $100)

Subtotal After the Discount: $41.16 (With 2% discount added)

Sales Tax Amount: $2.4696 (6% Tax since your subtotal after the discount is less than $100)

Total Amount Paid: $43.6296 (With 6% Sales Tax added)

..................................................................................................... Refund Policy: 100% if an error is reported within 30 days from the date of payment. Only 75% refund after 30 days. Thank you for prompt payment.


heres my input file

Austin City Office, Texas
RECEIPT #59, September28, 2013, 09:00PM
Refund Policy: 100% if an error is reported within 30 days from the date of payment. Only 75% refund 
after 30 days.
Thank you for prompt payment.
127654
Jack Jones
2059 Joe Lane, Austin TX, 78646
512-520-5862
2
8
4
2
8
4
2
8
4
Austin City Office, Texas
RECEIPT #59, September28, 2013, 09:00PM
Refund Policy: 100% if an error is reported within 30 days from the date of payment. Only 75% refund 
after 30 days.
Thank you for prompt payment.
124325
Jack Williams
2788 Eagle Drive, Austin TX, 78646
512-623-7676
2
8
20
2
8
20
2
8
20
Austin City Office, Texas
RECEIPT #59, September28, 2013, 09:00PM
Refund Policy: 100% if an error is reported within 30 days from the date of payment. Only 75% refund 
after 30 days.
Thank you for prompt payment.
125672
John Jones
3422 Hawk Drive, Austin TX, 78646
512-522-4564
2
8
40
2
8
40
2
8
40

and heres my code

#include<iostream>
#include<iomanip>
#include<string>
#include<string>
#include<fstream>

using namespace std;

//define varibles
    int ncustomer1;
    double  discount, tax;
    string dc, dsc, tc, dtpc;
    //validation constant
    const int MIN_N = 1, MAX_N = 3, MAX_TITLE=200, MAX_CINFO=200;
    const float MIN_CHARGE=1.00, MAX_CHARGE= 1000.00;
    // Array constant
    const int MAX_NUMCUST=3, MAX_NUMMONTH=3, MAX_NUMCHARGE=3, MAX_NUMHEAD=6, MAX_NUMINFO=9, MAX_NUMTOTAL=8;
    //customer info array
    string NonNum[MAX_NUMCUST][MAX_NUMINFO];
    //charges array
    double Num[MAX_NUMCUST][MAX_NUMMONTH][MAX_NUMCHARGE] = {0};
     //calculated array
    double custTotals[MAX_NUMCUST][MAX_NUMTOTAL] = {0};

    //functions
    void input(string NonNum[MAX_NUMCUST][MAX_NUMINFO], double Num[MAX_NUMCUST][MAX_NUMMONTH][MAX_NUMCHARGE], int& count);
    double subtotal(double custTotals[MAX_NUMCUST][MAX_NUMTOTAL], int&count);
    double discount1(double custTotals[MAX_NUMCUST][MAX_NUMTOTAL], int&count);
    double tax1(double custTotals[MAX_NUMCUST][MAX_NUMTOTAL], int&count);
    void receipts(double custTotals[MAX_NUMCUST][MAX_NUMTOTAL], string NonNum[MAX_NUMCUST][MAX_NUMINFO], int&count);

int main()

{
    //Ask number of customers from user
        cout<< "Enter a number for amount of customers you would like to make a receipt for number should be between 1 and 3."<<endl;
        cin >> ncustomer1;

    //validate users entry
        while(ncustomer1 > MAX_N || ncustomer1 < MIN_N )
        {
            cout << "Error: the number of customers must be between "<< MIN_N << " and "<< MAX_N  <<endl;
            cout<< "Re-Enter the number of customers"<<endl;
            cin>> ncustomer1;
        }

    //output to screen when users entry is correct
        cout<< "Ok, individual receipt(s) will be added to the output file for "<< ncustomer1<< " customer(s)."<<endl;

        //customer for loop
    for (int count = 0; count < ncustomer1; ++count)
        {
        input(NonNum, Num, count);
        subtotal(custTotals, count);
        discount1(custTotals, count);
        tax1(custTotals, count);
        receipts(custTotals, NonNum, count);
        }

return 0;

}

//functions
void input(string NonNum[MAX_NUMCUST][MAX_NUMINFO], double Num[MAX_NUMCUST][MAX_NUMMONTH][MAX_NUMCHARGE], int& count)
{
    //objects to help read input file
                ifstream inputFile;

            //open the input file
                inputFile.open("Project5_a02418790_Input.txt");

            //validation of input file
                if(!inputFile)
                {
                    cout<<"error opening input file.";

                }
            // For loop for non numeric data id, number...
                        for(int head = 0; head < 9; ++head)
                            {
                                //Get customer data as strings from input
                                getline(inputFile,NonNum[count][head]);

/*                              Validate inputed customer data
                                if(NonNum[count][head].length()>MAX_CINFO)
                                    {
                                        cout<<"customer "<<count<<"(customers are from 0-X, so customer 1=0) heading "<<head<<" String is too long"<<endl;
                                        continue;
                                    }
*/
                            }//end non numeric data for loop


                //number of months For loop
                for(int mnth = 0; mnth < 3; ++mnth)
                    {

                        //number of charges For loop
                        for(int charge = 0; charge < 3; ++charge)
                            {
                                //input charges
                                inputFile >> Num[count][mnth][charge];

                                //Running totals of the 3 charges
                                custTotals[count][charge] += Num[count][mnth][charge];
                            }//end of number of charges for loop

                    }//end of number of months foor loop

}


double subtotal(double custTotals[MAX_NUMCUST][MAX_NUMTOTAL], int&count)
{
// calculate the subtotal
//subtotal          =    Elec total      +   Water Total      +   Gas Total
custTotals[count][3]=custTotals[count][0]+custTotals[count][1]+custTotals[count][2];

}

double discount1(double custTotals[MAX_NUMCUST][MAX_NUMTOTAL], int&count)
{
//figure out the discount based on the subtotal
                //if(subtotal=,<,> a number)
                //  discount%= x, comment= x;
                if(custTotals[count][3]<100)
                    discount= .02, dc = "(2% discount since your subtotal is less than $100)", dsc="(With 2% discount added)";
                if(custTotals[count][3]>=100&&custTotals[count][3]<250)
                    discount= .03, dc = "(3% discount since your subtotal is greater or equal to $100)", dsc="(With 3% discount added)";
                if(custTotals[count][3]>=250&&custTotals[count][3]<500)
                    discount=.04, dc = "(4% discount since your subtotal is greater or equal to $250)", dsc="(With 4% discount added)";
                if(custTotals[count][3]>=500)
                    discount=.05, dc = "(5% discount since subtotal is greater or equal to $500)", dsc="(With 5% discount added)";

            //calculate the amount of discount
            //discount amount      =     subtotal      * discount %
            custTotals[count][4] = custTotals[count][3]*discount;

            //calculate the subtotal after the discount
            //subtotal after dis=    subtotal        - discount
            custTotals[count][5]=custTotals[count][3]-custTotals[count][4];
}

double tax1(double custTotals[MAX_NUMCUST][MAX_NUMTOTAL], int&count)
{


    //figure out how sales tax percent and what captions
    //if(subtotal after dis =,<,> a num)
    //  tax percent= x, comment= x;
    if(custTotals[count][5]< 100 )
        tax= .06, tc="(6% Tax since your subtotal after the discount is less than $100)", dtpc= "(With 6% Sales Tax added)";
    if( custTotals[count][5] >=100&& custTotals[count][5] <250)
        tax= .07, tc="(7% Tax since your subtotal after the discount is greater or equal to $100)", dtpc= "(With 7% Sales Tax added)";
    if( custTotals[count][5] >=250&& custTotals[count][5] <500)
        tax=.08, tc="(8% Tax since your subtotal after the discount is greater or equal to $250)", dtpc= "(With 8% Sales Tax added)";
    if( custTotals[count][5] >=500)
        tax=.09, tc="(9% Tax since your subtotal after the discount is greater or equal to $500)", dtpc= "(With 9% Sales Tax added)";

//calculate the sales tax amount
//amount of tax    = subtotal after dis  * tax percent
custTotals[count][6]= custTotals[count][5]*tax;

//calculate total amount paid
//total paid       =  subtotal after dis   + amount of tax
custTotals[count][7]= custTotals[count][5] + custTotals[count][6];

}

void receipts(double custTotals[MAX_NUMCUST][MAX_NUMTOTAL], string NonNum[MAX_NUMCUST][MAX_NUMINFO], int&count)
{
    //objects to help read output file
                ofstream outputFile;

            //open the  output file
                outputFile.open("Project5_a02418790_Output.txt");

            //validation of output file
                if(!outputFile)
                {
                    cout<<"error opening output file.";

                }

//OUTPUT ALL NEEDED INFO (STILL INSIDE CUSTOMER FOR LOOP)
                        //OUTPUT HEADER
                        outputFile<<setw(58)<<NonNum[count][0]<<endl<<setw(70)<<NonNum[count][1]<<endl;

                        //OUTPUT CUSTOMER INFO FOR LOOP
                        for(int z = 5; z < 9; ++z)
                            {

                                while(z == 5 )//Customer ID
                                    {
                                        outputFile<<endl<<"Customer ID: "<<NonNum[count][z]<< endl;
                                        break;
                                    }

                                while(z == 6 )//Name
                                    {
                                        outputFile<<"Name: "<<NonNum[count][z]<< endl;
                                        break;
                                    }

                                while(z == 7 )//Address
                                    {
                                        outputFile<<"Address: "<<NonNum[count][z]<< endl;
                                        break;
                                    }

                                while(z == 8 )//Phone Number
                                    {
                                        outputFile<<"Phone Number: "<<NonNum[count][z]<< endl;
                                        break;
                                    }

                            }//END OF OUTPUT CUSTOMER INFO FOR LOOP

                        //OUTPUT CHARGES AND TOTALS FOR LOOP
                        for(int y = 0; y < 8; ++y)
                            {

                                while(y == 0 )//Electricity Charges
                                    {
                                        outputFile<<endl<<"Electricity Charges: $"<<custTotals[count][y] << endl;
                                        break;
                                    }

                                while(y == 1 )//Water Charges
                                    {
                                        outputFile<<"Water Charges: $"<<custTotals[count][y] << endl;
                                        break;
                                    }

                                while(y == 2 )//Gas Charges
                                    {
                                        outputFile<<"Gas Charges: $"<<custTotals[count][y] << endl<<endl;
                                        break;
                                    }

                                while(y == 3 )//Subtotal
                                    {
                                        outputFile<<"Subtotal: $"<<custTotals[count][y] << endl;
                                        break;
                                    }

                                while(y == 4)//Discount Amount
                                    {
                                        outputFile<<"Discount Amount: $"<<custTotals[count][y]<<" "<<dc<< endl<<endl;
                                        break;
                                    }

                                while(y == 5 )//Subtotal After the Discount
                                    {
                                        outputFile<<"Subtotal After the Discount: $"<<custTotals[count][y]<<" "<<dsc<< endl<<endl;
                                        break;
                                    }

                                while(y == 6 )//Sales Tax Amount
                                    {
                                        outputFile<<"Sales Tax Amount: $"<<custTotals[count][y]<<" "<<tc<< endl<<endl;
                                        break;
                                    }

                                while(y == 7 )//Total Amount Paid
                                    {
                                        outputFile<<"Total Amount Paid: $"<<custTotals[count][y]<<" "<<dtpc<< endl<<endl;
                                        break;
                                    }

                            }//END OF OUTPUT CHARGES AND TOTALS FOR LOOP


                        //OUTPUT FOOTER BREAK
                        outputFile<<"....................................................................................................."<<endl;

                        //OUTPUT REFUND FOR LOOP
                        for(int w = 2; w < 4; ++w)
                            {
                                outputFile<< NonNum[count][w]<<endl;
                            }

                        //OUTPUT THANKYOU
                        outputFile<<setw(58)<<NonNum[count][4]<<endl;

                        //OUTPUT NEW LINE AND DIVIDER FOR NEW CUSTOMER
                        outputFile<<endl<<"_____________________________________________________________________________________________________"<<endl<<endl;



}
  • i dont know why my input file uploaded like that if there is any other way to upload it i will. – user3000080 Nov 16 '13 at 19:34
  • Use a debugger to step through your code line at a time to see where it is going wrong. Inspect the contents of variables to assist with figuring out why. – JBentley Nov 16 '13 at 19:37
  • Also, use descriptive self-documenting names. Names such as dc, dsc, tc, dtpc, make the code a nightmare to read and understand. Avoid abbreviations. Every part of the name should describe something about it - names like `ncustomer1` are unreadable - what does the "n" mean? Why is there a "1"? The person reading the code (which may be a future you) shouldn't have to ask these questions. Prefer something like "numberOfCustomers" - now it is instantly understandable without further reading. – JBentley Nov 16 '13 at 19:38
  • As an extra point, your code is making heavy use of global variables - this is [rarely a good idea](http://stackoverflow.com/questions/484635/are-global-variables-bad). – JBentley Nov 16 '13 at 19:46
  • i just saw all of y'alls comments thanks a lot. and @JBentley our professor wants global constants for everything. heres a piece of the project description The number of customers (n) will be declared global. Also, use global constants for the size of arrays. – user3000080 Nov 16 '13 at 21:06

1 Answers1

0

Are you sure it writes the first one each time? It looks to me that it would write the last one because you write over the file each call to receipt instead of appending to it.

The key reason to getting one set of outputs IMHO is this line

outputFile.open("Project5_a02418790_Output.txt");

Because you call it every call to receipts you end up overwriting the file each time and get just one set of outputs.

There are a lot of other things that are very bad coding practice.

Issue1: Use of arrays where you should use Structures / or classes: For instance: You keep your customer information in arrays of arrays of strings.

std::string NonNum[MAX_NUMCUST][MAX_NUMINFO]

Then NonNum[1][5] is the ID of customerID of customer 1.. you should build a struct it will make your code much easier to understand. Name it properly NonNum tells us it contains strings which we know from glancing at the code, it doesn't tell us the important info of what kind of information is stores (Customer Id / Address etc..)

Also look at this:

for(int z = 5; z < 9; ++z) {
    while(z == 5 )//Customer ID  {
         outputFile<<endl<<"Customer ID: "<<NonNum[count][z]<< endl;
         break; 
    while(z==6) { ...

}

What is the point of the inner while? Why do you need to for loop? Wouldn't it be much easier to write:

outputFile<< "Customer ID:" << CustomerInfo[i].CustomerID << endl;

Issue2: Dependencies between functions

subtotal fills custTotals[i][3] and is dependent on custTotals[i][0], custTotals[i][1] & custTotals[i][2]

discount1 fills custTotals[i][4] based on the previous ones.. Again you are using an array where you should use a structure. But also it will make life much easier for you if the inputs and outputs to a function are clear and easy to understand.

Currently any change in the order of the functions will mess up the logic but it is impossible to see that from the code.

If you had a separate subTotals array that you would pass to subTotals so it would write to and then pass into Discount1 so it would read from everything becomes clearer.

Issue 3: you pass a int& count to all these functions although you do not plan to change it. I expected the error to be that you wrote to count in one of the inner function and didn't realize it. If you pass a non const ref to an object it indicates that this is a output of the function not an input.

odedsh
  • 2,594
  • 17
  • 17
  • i just looked over the output file and it is outputting the first customers info so i dont believe that it is overwriting. issue1; we are not allowed to use structures yet we will have to convert this code into structures for the next project, it sucks. issue2; let me see what i can do to edit that subtotal array. issue3; let me look over that i am still a little confused on functions we just started with them and iam not a cs major. – user3000080 Nov 16 '13 at 20:19
  • i also added the output file to my original question thanks @odedsh – user3000080 Nov 16 '13 at 20:26
  • So You have another problem. Each time you call the function Input you reopen the file. Which is why you keep working on the first set of data. So your loop basically opens the same input file again and again reading only the first set of data. It opens the same file output file again and again writing the same set of data – odedsh Nov 16 '13 at 21:40
  • yea i just realized that i fixed that using cin.ignore and now like you said before i am overwriting. How would i go about fixing that. if i could pull the opening of the output file out of my loop it would work fine i believe but then i cant write to it from inside the loop...? – user3000080 Nov 16 '13 at 21:55
  • Open the inputstream then pass it to your read_input function. Open the output stream and pass it to the function that does the writing. It is very common for reading / writing functions to accept an stream object use it and not take care of opening / closing the stream It allows them to read input from different sources (stdin / network / file / memory) and write output to different sources without changes to the code – odedsh Nov 16 '13 at 22:05
  • thanks alot for your help i just got done every thing works and i fixed it all up – user3000080 Nov 17 '13 at 00:16