Hope people dont mind (Lerner and iamthwee), but I would like to start a new post for this assignment of mine. since I think the length of the other one is putting people off and the code is now a lot different.

Can someone help me finalise this (has been going on for DAYS). There are only a few errors I believe.

I need to read (via piping) a txt file which has format:

3435344 @ L Brooks,12 Shaftsbury Road,Burwood NSW 2134
3435344 A 2005/02/22/08:22:41
3435344 A 2005/03/20/08:22:41
3435344 B 2005/03/23/18:22:41
3435344 B 2005/04/10/28:22:41
3435344 C 2005/03/11/08:22:41
3435344 C 2005/05/10/14:22:41
3435344 C 2005/05/19/06:22:43
3435344 D 2005/05/01/01:26:41
3873242 @ N McGoldrick,8 Colless Place,South Melbourne VIC 3205
3873242 B 2005/03/29/02:40:59
3873242 B 2005/05/16/02:40:59
3873242 C 2005/04/07/22:40:59
etc....

use, the cost of stations as A is $2.80, B is $ 2.30 etccc.

to print an invoice with totals per ID. (So one pages has total for ID 3435344, then totals for 3873242....)

This is the code I have prepared to date:

#include <iostream>
#include <string.h>
using namespace std;

void printGenericHeading(int&, int&);
void printCustomerHeading(int&, int&);
void readId (int& , int& , int& ,int&, int& );
void readNameAddress (int& , int& , string& , string& , string & , string& ,int& , int& );
void readDateTime (int& , int& , string& , string& , string& ,int& , int& );
void calculateTotalStation (string& , int , double& , double& , double& , double& , double& , double& , int& );
void resetControlTotals(double&);
void printTotalInvoice (int& , char& , double& , double& , double& , double& , double& );

const int MAX_DETAIL_LINES =100;
const int MAX_LINE = 100;
const int MAX_SIZE = 20;
double TotalInvoice = 0;
int pageCount = 0;
int lineCount = 0;
bool more= true;

void printGenericHeading(int& pageCount, int& lineCount)
{
     pageCount = pageCount +1;
     cout<<"INVOICE FOR TOLL EXPENSES"<<endl;
     cout<<"_________________________"<<endl;
     cout<<"TAG\tCUSTOMER\tSTATION"
     <<"\t\t\t\t\n";
     cout<<"ID\tNAME\t\tID\n";
     
     lineCount = 4;
     }
     
void printCustomerHeading(int& pageCount, int& lineCount)
{
     pageCount = pageCount +1;
     cout<<"\t\t\t\t\n";
     cout<<"t\t\t\t\tDATE\t\tTIME\tAMOUNT\n\n";
     
     lineCount = 3;
     }

void readId (int& i,int& id, int MAX_SIZE, int& count)
{
     id [MAX_SIZE];
     count = 0;
 do {
      
     cin>>id[i];
     }
     while (count<MAX_SIZE);
     
void readNameAddress (int& MAX_LINE, int& MAX_SIZE, string& name, string& address, string & line, string& inputString,int& count, int& position);
{
    
    name [MAX_SIZE];
    address [MAX_SIZE];
    line;
    count =0;
    
    do {
        getline(cin, line);   
        int position = line.find (',');
        name[count] = line.substr (0, position);
        address[count] = line.substr (position+1, MAX_LINE);
        count++;
        }
        while (count<MAX_SIZE);
        
        for (int i=0; i<count; i++)
        cout <<name[i]<<"\t"<<address[i]<<endl;
                      
} 
void readDateTime (int& MAX_LINE, int& MAX_SIZE, string& date, string& time, string& inputString,int& count, int& position);
{
    
    date [MAX_SIZE];
    time [MAX_SIZE];
    inputString;
    count =0;
    
    do {
        cerr<<"processing..."<<endl;
        getline(cin, inputString);   
        if(cin.fail()) break;  
        
        int position = inputString.find ('/');
        date [count] = inputString.substr(0, 10); 
        time [count]= inputString.substr(11,16-11); 
        count++;
        }
        while (count<MAX_SIZE);
        
        for (int i=0; i<count; i++)
        cout <<"t\t\t\t\t"<<date[i]<<"\t\t"<<time[i]<<endl;
                      
}
  void calculateTotalStation (string& station, int count, double& totalA, double& totalB, double& totalC, double& totalD, double& totalInvoice, double& controlTotal, int& lineCount)
{  
    totalA = 0;
    totalB = 0;
    totalC = 0;
    totalD = 0;
    
   int i = 0;
   do
   {
      
       if (station [i] = 'A')
       {               
                   totalA= totalA + 2.20;
                   cout<<totalA;
       }

     else if(station[i] = 'B')
     {               
                   totalB= totalB + 2.80;
                   cout<<totalB;
       }
        else if(station[i] == 'C')
     {               
                   totalC= totalC + 2.30;
                   cout<<totalC;
       }
        else if(station[i] == 'D')
     {               
                   totalD= totalD + 3.80;
                   cout<<totalD;
       }
       
        totalInvoice = totalA + totalB + totalC + totalD;
 cout<<"TOTAL:\t\t\t\t\t\t\$"<<setprecision(2)<<totalInvoice<<endl;
 cout<<"\t\t\t\t\t\t_______"<<endl;
 cout<<"\t\t\t\t\t\t_______"<<endl;
 cout<<"We thankyou for your prompt payment."<<endl;
 lineCount = lineCount + 4;
 resetControlTotals(controlTotal);
 
       
  }while(i < count);
  resetControlTotals(controlTotal);
}
     
     void resetControlTotals(double& controlTotal)
     
     {
     controlTotal = 0;  
     }



int main ()
{
int id;
int prevId;
string name;
string prevName;
double invoiceTotal;
double controlTotal;
int pageCount;
int lineCount;
int i;

readId (i, id, MAX_SIZE, count);
prevId =id;
prevName=name;
         while(more)
         {
               if (id!=prevId)
               {
               calculateTotalStation (station, count, totalA, totalB, totalC, totalD); 
               prevId= id;
               prevName = name;
               }
               if (lineCount >MAX_DETAIL_LINES)
               printGenericHeading(pageCount, lineCount);
               printCustomerHeading(pageCount, lineCount);
               calculateTotalStation (MAX_SIZE, station, count, totalA, totalB, totalC, totalD);
               readId (id, MAX_SIZE, count);
               readDateTime (MAX_LINE, MAX_SIZE, date, time, inputString, count, position); 
               readNameAddress (MAX_LINE, MAX_SIZE, name, address, line, string& inputString,int& count, int& position)
               }
               printTotalInvoice (MAX_SIZE, station, totalA, totalB, totalC, totalD, totalInvoice);

               system("pause");
               return 0;
}

Can someone help me finalise this? (DUEin the next couple of hours.)
Thanks!

Recommended Answers

All 5 Replies

And the errors are?

In this section:

void readId (int& i,int& id, int MAX_SIZE, int& count)
{
     id [MAX_SIZE]; ****
     count = 0;
 do {
      
     cin>>id[i];
     }
     while (count<MAX_SIZE);

It gives error 45 invalid types `int[int]' for array subscript at ******

In this code :

void readNameAddress (int& MAX_LINE, int& MAX_SIZE, string& name, string& address, string & line, string& inputString,int& count, int& position);
{
    
    name [MAX_SIZE]; **************
    address [MAX_SIZE];
    line;
    count =0;
    
    do {
        getline(cin, line);   
        int position = line.find (',');
        name[count] = line.substr (0, position);
        address[count] = line.substr (position+1, MAX_LINE);
        count++;
        }
        while (count<MAX_SIZE);
        
        for (int i=0; i<count; i++)
        cout <<name[i]<<"\t"<<address[i]<<endl;
                      
}

it gives error 56 `name' undeclared (first use this function) at *********

I'll leave it at that for starters...

You need to type them. eg

to delcare a string of names you have to specify the array is a string that holds X amount ...

string Names[100]

also another thing why are you pasing MAXSIZE to the function as a parameter?? Its a global meaning you only have to declare it once and you can use it anywhere in your program.

Following is a detailed critique of your program as posted and an incomplete program demonstrating how I
would use parallel arrays to complete the project.

#include <iostream>
#include <string.h>
using namespace std;

void printGenericHeading(int&, int&);
void printCustomerHeading(int&, int&);
void readId (int& , int& , int& ,int&, int& );
void readNameAddress (int& , int& , string& , string& , string & , string& ,int& , int& );
void readDateTime (int& , int& , string& , string& , string& ,int& , int& );
void calculateTotalStation (string& , int , double& , double& , double& , double& , double& , double& , int& );
void resetControlTotals(double&);
void printTotalInvoice (int& , char& , double& , double& , double& , double& , double& );

const int MAX_DETAIL_LINES =100;
const int MAX_LINE = 100;
const int MAX_SIZE = 20;
double TotalInvoice = 0;
int pageCount = 0;
int lineCount = 0;
bool more= true;


//pageCount and lineCount are glogal variables and shouldn't be passed as parameters
void printGenericHeading(int& pageCount, int& lineCount)
{
     pageCount = pageCount +1;
     cout<<"INVOICE FOR TOLL EXPENSES"<<endl;
     cout<<"_________________________"<<endl;
     cout<<"TAG\tCUSTOMER\tSTATION"
     <<"\t\t\t\t\n";
     cout<<"ID\tNAME\t\tID\n";
     
     lineCount = 4;
     }

//pageCount and lineCount are global variables and shouldn't be passed as parameters     
void printCustomerHeading(int& pageCount, int& lineCount)
{
     pageCount = pageCount +1;
     cout<<"\t\t\t\t\n";
     cout<<"t\t\t\t\tDATE\t\tTIME\tAMOUNT\n\n";
     
     lineCount = 3;
     }

//MAX_SIZE is a global variable and shouldn't be passed as a parameter
void readId (int& i,int& id, int MAX_SIZE, int& count)
{
     id [MAX_SIZE]; //this is an illegal statement, as MAX_SIZE is not a valid index, MAX_SIZE minus 1 is 
                    //the largest valid index.  MAX_SIZE would be the appropriate value if you were 
                    //declaring an array of ID like this:  int id[MAX_SIZE];
     count = 0;     
 do {
      
     cin>>id[i];  //cin is for input from keyboard, not for reading from file
     }
     while (count<MAX_SIZE); //count will always be zero, therefore this is an infinite loop

     //you should really only be reading one ID at a time.  It is the first field of each line in the file.
     //this will try to force each field in the line into an id until MAX_SIZE ids have been read in
//there is a missing } here to indicate end of function
 

//MAX_LINE, MAX_SIZE are global variables and shouldn't be used as parameters    
void readNameAddress (int& MAX_LINE, int& MAX_SIZE, string& name, string& address, string & line, string& inputString,int& count, int& position);
{
    
    name [MAX_SIZE];    //name is a reference to a single string passed as a parameter, therefore you can't use the [] operator
    address [MAX_SIZE]; //address is a reference to a single string passed as a parameter, therefore you can't use the [] operator
    line;               //this is a meaningless statement
    count =0;
    
    //this loop looks like you are trying to read all the names and addresses in at once and storing them in arrays
    //this would work if all the names/address information were sequential in the file, but they are not
    //you need to read them one at a time as they are found, as indicated by the @ char in the file in the station field
    do {
        getline(cin, line);   //you need a filestream here, not cin, to read from the file
        int position = line.find (',');  
        name[count] = line.substr (0, position);
        address[count] = line.substr (position+1, MAX_LINE); //you don't need MAX_LINE here at all.  Just use the first parameter.
        count++;
        }
        while (count<MAX_SIZE);
        
        for (int i=0; i<count; i++)
        cout <<name[i]<<"\t"<<address[i]<<endl;  //please indent this line to show it is the body of the for loop in a single line
                      
} 


//MAX_LINE and MAX_SIZE are global variables and shouldn't be sent as parameters

void readDateTime (int& MAX_LINE, int& MAX_SIZE, string& date, string& time, string& inputString,int& count, int& position);
{
    
    date [MAX_SIZE]; //date is a reference to a string, not an array, passed as a parameter, therefore the [] is invalid
    inputString;     //this is a meaningless statement
    count =0;
    
    //again this loop is an attempt to read in date and time data as if it were sequential in the file, but it isn't
    //therefore this will fail.
    do {
        cerr<<"processing..."<<endl;
        getline(cin, inputString);   //should be using a file stream, not cin, to read from file
        if(cin.fail()) break;        
        
        int position = inputString.find ('/');//you don't use position in the next two lines, so this line is unecessary
        date [count] = inputString.substr(0, 10); 
        time [count]= inputString.substr(11,16-11); 
        count++;
        }
        while (count<MAX_SIZE);
        
        for (int i=0; i<count; i++)
        cout <<"t\t\t\t\t"<<date[i]<<"\t\t"<<time[i]<<endl;  //again indent this line to help yourself, or others
                      
}


  void calculateTotalStation (string& station, int count, double& totalA, double& totalB, double& totalC, double& totalD, double& totalInvoice, double& controlTotal, int& lineCount)
{  
    totalA = 0;
    totalB = 0;
    totalC = 0;
    totalD = 0;
    
   //this function will calculate the total the totals of each station and the total of all stations added together
   //if all stations visited by a given person are stored in an array called station.  For this to work the array
   //must be only data for a single person and must be filled element by element as the file is being read
   //but I can't find use of station or declaration of station outside of this function, which is a problem.
   //The other functions try, but fail, to get all ids, all name/addresses, and all date/times in an array
   //so what you could do is get all station A in an array, and all station B in a separate array, and all station C in a
   //a separate array, etc.  Then when it comes time to calculate totals you can do it index by index where each index 
   //represents a different person.

   //If you want to do calculations one person at a time as they are being read from file, then the following code, with 
   //corrections could work, but it won't work in conjunction with the other functions.     
   int i = 0;
   do
   {
      
       if (station [i] = 'A') //station is a reference to a string variable, not an array of strings, therefore the [] is invalid
       {                      //'A'is char, "A" is a string, station[i] would be a string if station were an array
                              //= is the assignment operator, you want the equal operator
                               
                   totalA= totalA + 2.20;
                   cout<<totalA;
       }

     else if(station[i] = 'B') //same problems as for station[i] = 'A'
     {               
                   totalB= totalB + 2.80;
                   cout<<totalB;
       }
        else if(station[i] == 'C') //same problems as for station[i] = 'A'
     {               
                   totalC= totalC + 2.30;
                   cout<<totalC;
       }
        else if(station[i] == 'D') //same problems as for station[i] = 'A'
     {               
                   totalD= totalD + 3.80;
                   cout<<totalD;
       }
       
   //the following lines should be outside of the do/while loop to be done just once per call to calculateTotalStation
        totalInvoice = totalA + totalB + totalC + totalD;
 cout<<"TOTAL:\t\t\t\t\t\t\$"<<setprecision(2)<<totalInvoice<<endl;
 cout<<"\t\t\t\t\t\t_______"<<endl;
 cout<<"\t\t\t\t\t\t_______"<<endl;
 cout<<"We thankyou for your prompt payment."<<endl;
 lineCount = lineCount + 4;
 resetControlTotals(controlTotal);
 
       
  }while(i < count);

   
  resetControlTotals(controlTotal);
}
     
     void resetControlTotals(double& controlTotal)
     
     {
     controlTotal = 0;  
     }



int main ()
{
int id;
int prevId;
string name;
string prevName;
double invoiceTotal;
double controlTotal;
int pageCount;  //this is a duplicate declaration of pageCount
int lineCount;  //this is a duplicate declaration of lineCount
int i;

readId (i, id, MAX_SIZE, count);
prevId =id;
prevName=name;
         while(more)
         {
               if (id!=prevId)
               {
               calculateTotalStation (station, count, totalA, totalB, totalC, totalD); 
               prevId= id;
               prevName = name;
               }
               if (lineCount >MAX_DETAIL_LINES) //how many of the following lines do you want in body of this if???
               printGenericHeading(pageCount, lineCount);
               printCustomerHeading(pageCount, lineCount);
               calculateTotalStation (MAX_SIZE, station, count, totalA, totalB, totalC, totalD);
               readId (id, MAX_SIZE, count);
               readDateTime (MAX_LINE, MAX_SIZE, date, time, inputString, count, position); 
               readNameAddress (MAX_LINE, MAX_SIZE, name, address, line, string& inputString,int& count, int& position)
               } //this will close out the while loop, it should be indented under the opening brace for the while loop
                 //more is never changed anywhere in the functions so it will always be true.  Therefore this is an 
                 //infinite loop
               printTotalInvoice (MAX_SIZE, station, totalA, totalB, totalC, totalD, totalInvoice);

               system("pause");
               return 0;
}

By posting the following I am breaking two rules.

First I am giving you an almost complete solution
to the project. True, it won't work by just a straight copy and paste, but it's pretty darn close to
that.

Second, the following doesn't follow a basic tenet that I follow when writing code for myself. That
tenet is to write no more than a single function before I compile looking for errors. I have not
compiled the following at all. I have no idea how many unintentional errors there are, though I know
I have left some intentional errors such as not completing statements in a couple places, etc.
I think a major part of the code you posted stems from not following same process. You should write
a single function or segment of code and check to see if it does what you want. You should also
write for the specific first and then write to generalize second, unless you are clear how you are
going to generalize. So I would ideally have written code to read just the first line of the file and
make sure I could get an id, station and name/date string. Then I would write code to break the
name/date string apart. Then I would figure out how to read the second line from the file and figure
out how to break it apart. Then I would figure out how to read the entire file line by line. Then
I would figure out how to switch from one person to the next. With each step I would add variables
to the top of the program as necessary to complete each step.

Writing a whole program and then trying to compile debug leads to lots of problems, and lots of problems
that just keep repeating themselves, as in your program code.

#include <iostream>
#include <fstream>  //for stream to read from file
using namespace std;

const int MAX_SIZE = 100;


//GOAL:  read file data into parallel arrays such that there is a unique index for each person
int main()
{
   int count = 0; //to keep track of which index is being used   
   int prevID = 0;     //to help determine when new id found
   char station;  //may be @, A, B, C, or D
   string temp; //holding string

   //declare parallel arrays to keep track of data from files needed to print invoices
   int id[MAX_SIZE]; //to keep track of the id for each index
   string name[MAX_SIZE]; //to keep track of the name for each index
   string address[MAX_SIZE]; //to keep track of the address of each index
   int stationA[MAX_SIZE] = {0}; //to keep track of the number of times station A is found for each id
   int stationB{MAX_SIZE] = {0}; //to keep track of the number of times station B is found for each id
   int stationC[MAX_SIZE] = {0}; //to keep track of the number of times station C is found for each id
   int stationD[MAX_SIZE] = {0]; //to keep track of the number of times station D is found for each id
   double totalAmount[MAX_SIZE];    //to keep track of the total amount of a given invoice for a given id

   
   string dateTime = "06/01/2006/18:00:01"; //date and time of invoice being printed
   
   ifstream fin("InputData.txt");
   if(!fin)
   {
     cerr << "unable to open input file" << endl;
     exit(1);
   }
   
   while(fin >> id[count]) //loop will stop when fin goes into fail state
                           //if a new id is found, assume the rest of the information is present as well
   {
      fin >> station;
      fin.ignore();
     
      getline(fin, temp);
      
      if(prevId == id)  //then increment station visited for this index
      {
        if(station == 'A')
          stationA[count] = stationA[count] + 1;
        else if(station == 'B')
          stationB[count] = stationB[count] + 1;
        else if(station == 'C') 
          stationC[count] = stationC[count] + 1;
        else if(station == 'D')
          stationD[count] = stationD[count] + 1;
        else
        {
          cerr << "error in file contents" << endl;
          exit(1);
        }
        
        //date and time are meaningless as far as I'm concerned, if you want to do something with it
        //the string is in temp
      }
      else
      {
        //station is meaningless in this line so forget it

        //have a new persons data now so increment count to move on to next index
        ++count;
        
        //name/address are now in temp and need to be separated into separate strings here and stored 
        //in the new index of the appropriate arrays
        name[count] = 
        address[count] = 
      }
    }
    
    //now that loop has ended determine why
    if(!fin.eof())
    {
      cerr << "file input error." << endl;
      exit(1);
    }
    //else
      //EOF found so all the data has been read into the appropriate parallel arrays so we can proceed
      //since fin isn't needed any more it can be left in the failed state
    
    //Now calculate total cost for each index
    for(int i = 0; i <= count; ++i)
      totalAmount[i] = stationA[i] * 2.20 + stationB[i] * 2.30 + stationC[i] * 2.80 + stationD[i] * whatever;

    //Now prepare create a report of all invoices all in the same code
    //Prepare an invoice for each person in the database.
    //There will be count + 1 number of invoices to print


    //A header for the overall report could go here if desired
    for(int i = 0; i <= count; ++i)  //index zero through count should be used  
    {
      //if you want to have a personalized header for each person it could go here
      cout << name[i] << ' ' << address[i] << endl;
      cout << "Date of invoice: 6/1/06";
      cout << "Total Due: " << totalAmount[i] << endl << endl;
    }
}

Second, the following doesn't follow a basic tenet that I follow when writing code for myself. That
tenet is to write no more than a single function before I compile looking for errors.

That's not so horrible. On one homework assignment, a sparse matrix implementation, I handed in code with multiplication, addition, subtraction, and assignment implemented, but I forgot to check if it even compiled, not to mention worked.

I got very lucky on that one :-)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.