C++/c++

Advertisement


Question
QUESTION: could you pls help mi,i realli realli need your help.i'm hving a veri hard time doing it.i'm trying to keeps track of customers’ portfolios, which include several bank accounts n investments.i'm nt sure whether i'm doing it correct anot,could u pls guide mi.i will be so appericated for all the help frm u.


The first file, customer.txt, has the following format:
customerID  firstName    lastName   address       phoneNum        Type
10001       Mickey    Mouse       Sengkang     91111111     Gold      ok
50020       Humpty    Dumpty       JurongWest     94444444     NORmal   ok
1001       Ben          Jerry       JurongEast     93333333     Normal   Error, ignore

The second file, account.txt, has the following format:
customerID accountNum   type     balance        numYears
10001      700001   SAVINGS    10000.00   2      ok
10001      70001   SAVINGS    10000.00   2      Error, ignore


The third file, investment.txt, has the following format:
customerID investNum    type    investValue     currValue
10001      3300001   Stock   10000.00   12000.00   ok
50020      33a00   Stock   10000.00   12000.00   Error, ignore


For the three input files above, all fields are not case-sensitive. If any entry has an invalid field, your program will ignore the entry entirely.
For bank accounts, the interest rates are derived based on following table:
CustomerType     AccountType  
         Savings
Normal          1.5%
Gold          Normal + 1.0%

Final balance is computed as original balance plus interest earned.
For investment accounts, the gain/loss is computed as the difference between current value and invested value.

output:

*** Overall Customer Statistics ***       
Number of customers type Normal: 1      
Number of customers type Gold: 1      
Total number of customers: 2      
     
     
*** Individual Customer Statistics ***       
*** Customer Particulars ***      
Customer ID: 10001      
Name: Mickey Mouse      
Address: Sengkang      
Phone: 91111111      
Customer Type: Gold


*** Bank accounts ***   
Number: 700001   
Type: Savings   
Original Balance: $10000.00   
Num of years: 2   
Interest earned: $500.00    
Final Balance: $10500.00   
  

*** Investment accounts ***   
Number: 3300001   
Type: Stock   
Invested value: $10000.00   
Current value: $12000.00   
Gain/ Loss: $2000.00   
  


code:
#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;

class Customer
{
 public:
   Customer () {}
   void setCustomer(int, string, string, string, int, int);
   void display();

 private:
   int customerID;
   string firstName;
  string lastName;
   string address;
  int phoneNum;
  int type;
};

void Customer::setCustomer(int id, string fn, string ln, string a, int pn, int ct)
{
    customerID = id;
   firstName = fn;
   lastName = ln;
    address = a;
   phoneNum = pn;
   type = ct;
}

void Customer::display()
{
   cout << customerID << '\t' << firstName << '\t' << lastName
       << '\t' << address << '\t' << phoneNum << '\t' << type << endl;
}

class Account
{
 public:
   Account () {}
   void setAccount(int, int, int, int);
   void display();

 private:
   int accountNum;
   int type;
  int balance;
  int numYears;
};

void Account::setAccount(int an, int tp, int bl, int ny)
{
    accountNum = an;
   type = tp;
   balance = bl;
    numYears = ny;
}

void Account::display()
{
   cout << accountNum << '\t' << type << '\t' << balance
       << '\t' <<numYears << endl;
}

class Investment
{
 public:
   Investment () {}
   void setInvestment(int, int, int, int);
   void display();

 private:
   int investNum;
  int type;
  int investValue;
  int currentValue;

};

void Investment::setInvestment(int in, int tp, int iv, int cv)
{
    investNum = in;
   type = tp;
   investValue = iv;
    currentValue = cv;
}

void Investment::display()
{
   cout << investNum << '\t' << type << '\t' << investValue
       << '\t' << currentValue << endl;
}

int main()
{
 char buffer[256];

 ifstream in ("customers.txt");

 if (!in.is_open())
 {
    cout << "Error opening file";
    exit (1);
 }

 while (!in.eof() )
 {
   in.getline (buffer,100);
   cout << buffer << endl;
 }
 
 system("pause");
 return 0;
}



     

     


ANSWER: Hello Lisa.


You've made a good start defining the types of classes you need but you are having trouble reading from the file. I'm going to make some suggestions for the Customer class, then if you like my ideas, you can make similar changes to the other classes. You might also need to save your customers somewhere so you can count them before printing them out. Do you know how to use the standard template vector class? If not, I can help you with that, but the first thing to do is write code to read the files.


You will need these header files:
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
#include <sstream>


I suggest that each class has its own input function to read from its own file. Each class should know how its file is formatted. The main program should not have to worry about that.

For example, the Customer class could have a method like this:
bool read(ifstream& fin);
to read from fin. It reads one customer, and returns true if everything was correct, false otherwise.

The whole class looks like this:

class Customer
{
public:
   enum CustomerType
   {
       Normal = 1,
       Gold
   };

   Customer () {}
   void setCustomer(int, string, string, string, int, CustomerType);
   void display();
   bool read(ifstream& fin);

private:
   int customerID;
   string firstName;
   string lastName;
   string address;
   int phoneNum;
   CustomerType type;

   static const int ID_LENGTH = 5;
   static const int PHONE_LENGTH = 8;
};

I've made a few additions to your class. I've added constants for the correct ID length and phone length and I'm using an enumeration instead of a plain integer for storing the customer type.

My idea of the read method looks like this:

bool Customer::read(ifstream& fin)
{
   // First read individual strings from the file
   string idText;
   string firstNameText;
   string lastNameText;
   string addressText;
   string phoneText;
   string typeText;


   // Read the entire line in, then create a string stream from the line.
   // The string stream will break the line down into its pieces.
   string line;
   getline(fin, line);
   istringstream ss(line);
   ss >> idText >> firstNameText >> lastNameText >> addressText >> phoneText >> typeText;


   // Now check that each input is valid

   // Check ID
   if (idText.length() != ID_LENGTH || !allDigits(idText)) return false;

   // Check names
   if (firstNameText.length() == 0) return false;
   if (lastNameText.length() == 0) return false;

   // Check address
   if (addressText.length() == 0) return false;

   // Check phone
   if (phoneText.length() != PHONE_LENGTH || !allDigits(phoneText)) return false;

   // Check customer type
   CustomerType inputType;
   toLowerCase(typeText);
   if (strcmp(typeText.c_str(), "normal") == 0) inputType = Normal;
   else if (strcmp(typeText.c_str(), "gold") == 0) inputType = Gold;
   else return false;

   // Now assign all inputs to the customer
   setCustomer(atoi(idText.c_str()),
         firstNameText,
         lastNameText,
         addressText,
         atoi(phoneText.c_str()),
         inputType);
   return true;
}


Notice that I first read everything into temporary variables that end in "Text". Then I check each input for the correct length, and the correct format. If everything looks OK, then I call setCustomer.

Now you need two helper functions. The function allDigits(const string& input) returns true if the string is all digits, and false otherwise. It looks like this:

bool allDigits(const string& input)
{
   for(size_t ix = 0; ix < input.size(); ++ix)
   {
       if (!isdigit(input[ix])) return false;
   }
   return true;
}

For strings that are not case sensitive, it is best to put them into lower case with this function:

void toLowerCase(string& input)
{
   for(size_t ix = 0; ix < input.size(); ++ix) input[ix] = tolower(input[ix]);
}

The isdigit, and tolower functions are part of the standard C library.


In the main function you can open the customer file, and then have a customer object read the file like this:

int main()
{
   ifstream in ("customer.txt");

   if (!in.is_open())
   {
       cout << "Error opening file";
       exit (1);
   }

   Customer c;
   while (!in.eof())
   {
       if (c.read(in)) c.display();
   }
}


Good luck. Let me know how it goes.
Kind regards.
Zlatko


---------- FOLLOW-UP ----------

QUESTION: thankz veri much for answering my qns.i realli appericated for all the help frm u.i do nt knw hw to use the standard template vector class.could u pls help mi,as i nt sure whether i hv done correctly for reading all the files.


code:
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
#include <sstream>

using namespace std;


class Customer
{
public:
      enum CustomerType
      {
        Normal = 1,
        Gold,
      Silver,
      Platinum
      };
     
      Customer () {}
      void setCustomer(int, string, string, string, int, CustomerType);
      void display();
      bool read(ifstream& fin);
     void toLowerCase(string&);
     bool allDigits(const string& input);
 
private:
       int customerID;
     string firstName;
       string lastName;
       string address;
     int phoneNum;
       CustomerType type;

       static const int ID_LENGTH = 5;
       static const int PHONE_LENGTH = 8;
};

class Account
{
public:
      enum AccountType
      {
        Savings = 1,
        Checkings,
      FixedDeposit
      };
     
      Account () {}
      void setAccount(int, int, AccountType, int, int);
      void display();
      bool read(ifstream& fin);
     void toLowerCase(string&);
     bool allDigits(const string& input);
 
private:
       int customerID;
     int accountNum;
     int balance;
     int numYears;
       AccountType type;

       static const int ID_LENGTH = 5;
     static const int ACCOUNT_LENGTH = 6;

};

class Investment
{
public:
      enum InvestmentType
      {
        Stock = 1,
      RealEstate
      };
     
      Investment () {}
      void setInvestment(int, int, InvestmentType, int, int);
      void display();
      bool read(ifstream& fin);
     void toLowerCase(string&);
     bool allDigits(const string& input);
 
private:
       int customerID;
     int investNum;
     int investValue;
     int currValue;
       InvestmentType type;
     
     static const int ID_LENGTH = 5;
     static const int INVESTNUM_LENGTH = 7;

};


void Customer::setCustomer(int id, string fn, string ln, string a, int pn, CustomerType)
{
   customerID = id;
   firstName = fn;
   lastName = ln;
    address = a;
   phoneNum = pn;
}

void Customer::display()
{
   cout << "*** Individual Customer Statistics ***" << endl;       
   cout << "*** Customer Particulars ***" << endl;
  cout << customerID << '   ' << firstName << '   ' << lastName
       << '   ' << address << '   ' << phoneNum << '   ' << type << endl;
}

bool Customer::read(ifstream& fin)
{
  // First read individual strings from the file
  string idText;
  string firstNameText;
  string lastNameText;
  string addressText;
  string phoneText;
  string typeText;


  // Read the entire line in, then create a string stream from the line.
  // The string stream will break the line down into its pieces.
  string line;
  getline(fin, line);
  istringstream ss (line);
  ss >> idText >> firstNameText >> lastNameText >> addressText >> phoneText >> typeText;


  // Now check that each input is valid

  // Check ID
  if (idText.length() != ID_LENGTH || !allDigits(idText)) return false;

  // Check names
  if (firstNameText.length() == 0) return false;
  if (lastNameText.length() == 0) return false;

  // Check address
  if (addressText.length() == 0) return false;

  // Check phone
  if (phoneText.length() != PHONE_LENGTH || !allDigits(phoneText)) return false;

  // Check customer type
  CustomerType inputType;
  toLowerCase(typeText);
  if (strcmp(typeText.c_str(), "normal") == 0) inputType = Normal;
  else if (strcmp(typeText.c_str(), "gold") == 0) inputType = Gold;
  else if (strcmp(typeText.c_str(), "silver") == 0) inputType = Silver;
  else if (strcmp(typeText.c_str(), "platinum") == 0) inputType = Platinum;
  else return false;

  // Now assign all inputs to the customer
  setCustomer(atoi(idText.c_str()),
         firstNameText,
         lastNameText,
         addressText,
         atoi(phoneText.c_str()),
         inputType);
  return true;
}

void Account::setAccount(int id, int an, AccountType, int bl, int ny)
{
   customerID = id;
   accountNum = an;
   balance = bl;
   numYears = ny;
}

void Account::display()
{     
   cout << "*** Bank accounts ***   " << endl;
  cout << customerID << '   ' << accountNum << '   ' << type << '   ' << balance << '   ' << numYears << endl;
}

bool Account::read(ifstream& fin)
{
  // First read individual data from the file
  string idText;
  string accountNumText;
  string typeText;
  string balanceText;
  string numYearsText;
  


  // Read the entire line in, then create a string stream from the line.
  // The string stream will break the line down into its pieces.
  string line;
  getline(fin, line);
  istringstream ss (line);
  ss >> idText >> accountNumText >> typeText >> balanceText >> numYearsText;


  // Now check that each input is valid
  
  // Check ID
  if (idText.length() != ID_LENGTH || !allDigits(idText)) return false;

  // Check AccountNum
  if (accountNumText.length() != ACCOUNT_LENGTH || !allDigits(accountNumText)) return false;
  
  // Check account type
  AccountType inputType;
  toLowerCase(typeText);
  if (strcmp(typeText.c_str(), "savings") == 0) inputType = Savings;
  else if (strcmp(typeText.c_str(), "checkings") == 0) inputType = Checkings;
  else if (strcmp(typeText.c_str(), "fixed deposit") == 0) inputType = FixedDeposit;
  else return false;

  // Check balance
  if (balanceText.length() == 0) return false;

  // Check years
  if (numYearsText.length() == 0) return false;
  
  // Now assign all inputs to the account
  setAccount(atoi(idText.c_str()),
         accountNumText,
         inputType,
         balanceText,
         numYearsText);
  return true;
 
}


void Investment::setInvestment(int id, int in, InvestmentType, int iv, int cv)
{
   customerID = id;
   investNum = in;
   investValue = iv;
   currValue = cv;
}

void Investment::display()
{     
   cout << "*** Bank accounts ***   " << endl;
  cout << customerID << '   ' << investNum << '   ' << type << '   ' << investValue << '   ' << currValue << endl;
}

bool Investment::read(ifstream& fin)
{
  // First read individual data from the file
  string idText;
  string investNumText;
  string typeText;
  string investValueText;
  string currValueText;
  


  // Read the entire line in, then create a string stream from the line.
  // The string stream will break the line down into its pieces.
  string line;
  getline(fin, line);
  istringstream ss (line);
  ss >> idText >> investNumText >> typeText >> investValueText >> currValueText;


  // Now check that each input is valid
  
  // Check ID
  if (idText.length() != ID_LENGTH || !allDigits(idText)) return false;

  // Check AccountNum
  if (investNumText.length() != INVESTNUM_LENGTH || !allDigits(investNumText)) return false;
  
  // Check account type
  InvestmentType inputType;
  toLowerCase(typeText);
  if (strcmp(typeText.c_str(), "stock") == 0) inputType = Stock;
  else if (strcmp(typeText.c_str(), "realestate") == 0) inputType =  RealEstate;
  else return false;

  // Check invest value
  if (investValueText.length() == 0) return false;

  // Check current value
  if (currValueText.length() == 0) return false;
  
  // Now assign all inputs to the investment
  setInvestment(atoi(idText.c_str()),
         investNumText,
         inputType,
         investValueText,
         currValueText);
  return true;

  
}


bool allDigits(const string& input)
{
  for(size_t ix = 0; ix < input.size(); ++ix)
  {
      if (!isdigit(input[ix])) return false;
  }
  return true;
}

void toLowerCase(string& input)
{
  for(size_t ix = 0; ix < input.size(); ++ix) input[ix] = tolower(input[ix]);
}


int main()
{
  ifstream in ("customers.txt","account.txt","investment.txt");

  if (!in.is_open())
  {
      cout << "Error opening file";
      exit (1);
  }

  Customer c;
  Account a;
  Investment i;
  while (!in.eof())
  {
      if (c.read(in)) c.display();
     if (a.read(in)) a.display();
     if (i.read(in)) i.display();
  }
  
  return 0;
}



ANSWER: Hello Lisa.

Your program does not compile. I have made corrections to the program to make it compile. The code is at the very end of this message. Please try to fix your compiler errors before posting your code. If your code compiles, then you can also do some testing and learn how to fix your own errors.

These were the errors:
================================================================
1) You cannot have many characters between single quotes. You cannot have 'xxx'. You need double quotes for that. Like this: "xxx"

2) In many cases you were passing strings to functions that needed integers, you must call atoi(string.c_str()) to convert a string to an integer.

3) Your way of opening files is very creative but wrong. A file stream can access only one file at a time. Please have a look at the main program to see how its done.

4) The toLowerCase and allDigits are not part of any class. They are helper functions for all to use.


Now I have some suggestions:
=================================================================
When dealing with money, you should use floating point numbers instead of integers. You will need to use atof, instead of atoi to convert a string to floating point. You should declare your functions to take doubles for money instead of integers. I will leave that up to you.


When you declare a method, it is good style to show the parameter names in addition to the types.
For example:
   void setCustomer(int, string, string, string, int, CustomerType);
is more readable as:
   void setCustomer(int id, string fn, string ln, string a, int pn, CustomerType type);
Also, you should use more descriptive variable names.


Output:
=================================================================
The output of the program using my own test files is here below. Notice the number -858993460, it is caused by an uninitialized value in your classes. You must find out what that value is and why it is not being initialized. Ask yourself, what is being printed, where should it be initialized, and why is it not initialized.

*** Individual Customer Statistics ***
*** Customer Particulars ***
10001 Mickey     Mouse       Sengkang       91111111      -858993460
*** Individual Customer Statistics ***
*** Customer Particulars ***
50020 Humpty     Dumpty       JurongWest       94444444      -858993460
*** Bank accounts ***
10001 700001    -858993460  10000       2
*** Bank accounts ***
10002 700002    -858993460  10000       2
*** Investments ***
10001 3300001     -858993460  10000   12000
*** Investments ***
10003 3300003     -858993460  10000   13000



Next Steps:
=================================================================
Test the code below with your own files.

If you need to print out the overall customer statistics before the individual customers, you will need to delay printing the individual customers until all your counting is done. You can do the counting while you read in the customers, but then you must store each customer somewhere for printing later. Try storing it in an array. Show me what you come up with.

Best regards.
Zlatko





Code:
=================================================================
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
#include <sstream>

using namespace std;

bool allDigits(const string& input)
{
   for(size_t ix = 0; ix < input.size(); ++ix)
   {
       if (!isdigit(input[ix])) return false;
   }
   return true;
}

void toLowerCase(string& input)
{
   for(size_t ix = 0; ix < input.size(); ++ix) input[ix] = tolower(input[ix]);
}


class Customer
{
public:
   enum CustomerType
   {
       Normal = 1,
       Gold,
       Silver,
       Platinum
   };

   Customer () {}
   void setCustomer(int, string, string, string, int, CustomerType);
   void display();
   bool read(ifstream& fin);

private:
   int customerID;
   string firstName;
   string lastName;
   string address;
   int phoneNum;
   CustomerType type;

   static const int ID_LENGTH = 5;
   static const int PHONE_LENGTH = 8;
};

class Account
{
public:
   enum AccountType
   {
       Savings = 1,
       Checkings,
       FixedDeposit
   };

   Account () {}
   void setAccount(int, int, AccountType, int, int);
   void display();
   bool read(ifstream& fin);

private:
   int customerID;
   int accountNum;
   int balance;
   int numYears;
   AccountType type;

   static const int ID_LENGTH = 5;
   static const int ACCOUNT_LENGTH = 6;

};

class Investment
{
public:
   enum InvestmentType
   {
       Stock = 1,
       RealEstate
   };

   Investment () {}
   void setInvestment(int, int, InvestmentType, int, int);
   void display();
   bool read(ifstream& fin);

private:
   int customerID;
   int investNum;
   int investValue;
   int currValue;
   InvestmentType type;

   static const int ID_LENGTH = 5;
   static const int INVESTNUM_LENGTH = 7;

};


void Customer::setCustomer(int id, string fn, string ln, string a, int pn, CustomerType)
{
   customerID = id;
   firstName = fn;
   lastName = ln;
   address = a;
   phoneNum = pn;
}

void Customer::display()
{
   cout << "*** Individual Customer Statistics ***" << endl;
   cout << "*** Customer Particulars ***" << endl;
   cout << customerID << ' ' << firstName << "     " << lastName
       << "       " << address << "       " << phoneNum << "      " << type << endl;
}

bool Customer::read(ifstream& fin)
{
   // First read individual strings from the file
   string idText;
   string firstNameText;
   string lastNameText;
   string addressText;
   string phoneText;
   string typeText;


   // Read the entire line in, then create a string stream from the line.
   // The string stream will break the line down into its pieces.
   string line;
   getline(fin, line);
   istringstream ss (line);
   ss >> idText >> firstNameText >> lastNameText >> addressText >> phoneText >> typeText;


   // Now check that each input is valid

   // Check ID
   if (idText.length() != ID_LENGTH || !allDigits(idText)) return false;

   // Check names
   if (firstNameText.length() == 0) return false;
   if (lastNameText.length() == 0) return false;

   // Check address
   if (addressText.length() == 0) return false;

   // Check phone
   if (phoneText.length() != PHONE_LENGTH || !allDigits(phoneText)) return false;

   // Check customer type
   CustomerType inputType;
   toLowerCase(typeText);
   if (strcmp(typeText.c_str(), "normal") == 0) inputType = Normal;
   else if (strcmp(typeText.c_str(), "gold") == 0) inputType = Gold;
   else if (strcmp(typeText.c_str(), "silver") == 0) inputType = Silver;
   else if (strcmp(typeText.c_str(), "platinum") == 0) inputType = Platinum;
   else return false;

   // Now assign all inputs to the customer
   setCustomer(atoi(idText.c_str()),
       firstNameText,
       lastNameText,
       addressText,
       atoi(phoneText.c_str()),
       inputType);
   return true;
}

void Account::setAccount(int id, int an, AccountType, int bl, int ny)
{
   customerID = id;
   accountNum = an;
   balance = bl;
   numYears = ny;
}

void Account::display()
{
   cout << "*** Bank accounts ***      " << endl;
   cout << customerID << ' ' << accountNum << "    " << type << "  " << balance << "       " << numYears << endl;
}

bool Account::read(ifstream& fin)
{
   // First read individual data from the file
   string idText;
   string accountNumText;
   string typeText;
   string balanceText;
   string numYearsText;



   // Read the entire line in, then create a string stream from the line.
   // The string stream will break the line down into its pieces.
   string line;
   getline(fin, line);
   istringstream ss (line);
   ss >> idText >> accountNumText >> typeText >> balanceText >> numYearsText;


   // Now check that each input is valid

   // Check ID
   if (idText.length() != ID_LENGTH || !allDigits(idText)) return false;

   // Check AccountNum
   if (accountNumText.length() != ACCOUNT_LENGTH || !allDigits(accountNumText)) return false;

   // Check account type
   AccountType inputType;
   toLowerCase(typeText);
   if (strcmp(typeText.c_str(), "savings") == 0) inputType = Savings;
   else if (strcmp(typeText.c_str(), "checkings") == 0) inputType = Checkings;
   else if (strcmp(typeText.c_str(), "fixed deposit") == 0) inputType = FixedDeposit;
   else return false;

   // Check balance
   if (balanceText.length() == 0) return false;

   // Check years
   if (numYearsText.length() == 0) return false;

   // Now assign all inputs to the account
   setAccount(atoi(idText.c_str()),
       atoi(accountNumText.c_str()),
       inputType,
       atoi(balanceText.c_str()),
       atoi(numYearsText.c_str()));
   return true;

}


void Investment::setInvestment(int id, int in, InvestmentType, int iv, int cv)
{
   customerID = id;
   investNum = in;
   investValue = iv;
   currValue = cv;
}

void Investment::display()
{
   cout << "*** Investments ***      " << endl;
   cout << customerID << ' ' << investNum << "     " << type << "  " << investValue << "   " << currValue << endl;
}

bool Investment::read(ifstream& fin)
{
   // First read individual data from the file
   string idText;
   string investNumText;
   string typeText;
   string investValueText;
   string currValueText;



   // Read the entire line in, then create a string stream from the line.
   // The string stream will break the line down into its pieces.
   string line;
   getline(fin, line);
   istringstream ss (line);
   ss >> idText >> investNumText >> typeText >> investValueText >> currValueText;


   // Now check that each input is valid

   // Check ID
   if (idText.length() != ID_LENGTH || !allDigits(idText)) return false;

   // Check AccountNum
   if (investNumText.length() != INVESTNUM_LENGTH || !allDigits(investNumText)) return false;

   // Check account type
   InvestmentType inputType;
   toLowerCase(typeText);
   if (strcmp(typeText.c_str(), "stock") == 0) inputType = Stock;
   else if (strcmp(typeText.c_str(), "realestate") == 0) inputType =  RealEstate;
   else return false;

   // Check invest value
   if (investValueText.length() == 0) return false;

   // Check current value
   if (currValueText.length() == 0) return false;

   // Now assign all inputs to the investment
   setInvestment(atoi(idText.c_str()),
       atoi(investNumText.c_str()),
       inputType,
       atoi(investValueText.c_str()),
       atoi(currValueText.c_str()));
   return true;


}


int main()
{
   ifstream customers("customers.txt");
   ifstream accounts("account.txt");
   ifstream investments("investment.txt");

   if (!customers.is_open())
   {
       cout << "Error opening customer file";
       exit (1);
   }

   if (!accounts.is_open())
   {
       cout << "Error opening accounts file";
       exit (1);
   }

   if (!investments.is_open())
   {
       cout << "Error opening investments file";
       exit (1);
   }


   Customer c;
   while (!customers.eof())
   {
       if (c.read(customers)) c.display();
   }

   Account a;
   while (!accounts.eof())
   {
       if (a.read(accounts)) a.display();
   }

   Investment i;
   while (!investments.eof())
   {
       if (i.read(investments)) i.display();
   }

   return 0;
}

---------- FOLLOW-UP ----------

QUESTION: could u pls help mi.i will be so greatly appericated for all the help frm u.i trying to do the static for the customers.wen i compile i keep hving errors.i realli do nt knw y.

code:
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
#include <sstream>

using namespace std;


class Customer
{
public:
       static int numType;
       
         enum CustomerType
         {
         Normal=1,
         Gold,
         Silver,
         Platinum
         };


  Customer () {}
  void setCustomer(int, string, string, string, int, CustomerType);
  void display();
  bool read(ifstream& fin);
  
  
private:
  int customerID;
  string firstName;
  string lastName;
  string address;
  int phoneNum;
  CustomerType type;


  static const int ID_LENGTH = 5;
  static const int PHONE_LENGTH = 8;
};

int Customer::numType = 0;

void Customer::setCustomer(int id, string fn, string ln, string a, int pn, CustomerType ct)
{
  customerID = id;
  firstName = fn;
  lastName = ln;
  address = a;
  phoneNum = pn;
  type = ct;
  
}

void Customer::display()
{
  cout << endl;
  cout << "*** Individual Customer Statistics ***" << endl;
  cout << "*** Customer Particulars ***" << endl;
  cout << "CustomerID: " << customerID << ' ' << "
Name: " << firstName << "  " <<  lastName << "  "
       << "
Address: " << address << " " << "
Phone: " << phoneNum << " " << "
Customer Type: " << type << endl;
     
 switch(type)
{
  case Normal:   cout << "Normal
";
         break;
  case Gold:     cout << "Gold
";
         break ;
  case Silver:   cout << "Silver
";
         break;
  case Platinum: cout << "Platinum
";
         break;
  default:       cout << "invalid value
";
}   
}

bool allDigits(const string& input)
{
  for(size_t ix = 0; ix < input.size(); ++ix)
  {
      if (!isdigit(input[ix])) return false;
  }
  return true;
}

void toLowerCase(string& input)
{
  for(size_t ix = 0; ix < input.size(); ++ix) input[ix] = tolower(input[ix]);
}


bool Customer::read(ifstream& fin)
{
  // First read individual strings from the file
  string idText;
  string firstNameText;
  string lastNameText;
  string addressText;
  string phoneText;
  string typeText;


  // Read the entire line in, then create a string stream from the line.
  // The string stream will break the line down into its pieces.
  string line;
  getline(fin, line);
  istringstream ss (line);
  ss >> idText >> firstNameText >> lastNameText >> addressText >> phoneText >> typeText;


  // Now check that each input is valid

  // Check ID
  if (idText.length() != ID_LENGTH || !allDigits(idText)) return false;

  // Check names
  if (firstNameText.length() == 0) return false;
  if (lastNameText.length() == 0) return false;

  // Check address
  if (addressText.length() == 0) return false;

  // Check phone
  if (phoneText.length() != PHONE_LENGTH || !allDigits(phoneText)) return false;

  // Check customer type
  CustomerType inputType;
  toLowerCase(typeText);
  if(typeText == "normal")inputType = Normal;
  else if (typeText =="gold")inputType = Gold;
  else if (typeText == "silver")inputType = Silver;
  else if (typeText == "platinum")inputType = Platinum;
  else return false;

  // Now assign all inputs to the customer
  setCustomer(atoi(idText.c_str()),
      firstNameText,
      lastNameText,
      addressText,
      atoi(phoneText.c_str()),
      inputType);
  return true;
}

  
void readFile(Customer[]);
void DisplayCustomer(Customer customerList[]);

int main()
{
  Customer customerList[6];
  int customerTotal = 0;
  char temp;
  int customerID,firstName,lastName,address,phoneNum,type;
  
  readFile(customerList);
  
  customerList[customerTotal] = *new Customer(customerID,firstName,lastName,address,phoneNum,type);
  customerTotal++;
     
  DisplayCustomer(customerList);
 
  system("pause");
  return 0;
 
}
 
void readFile(Customer customerList[])
{
   int num;
   int customerTotal = 0;
  int customerID,firstName,lastName,address,phoneNum,type;
  
  ifstream customers;
   
   customers.open("customers.txt");
   if (!customers.good())
   {
       cout << "File not found" << endl;
     exit(1);
   }
  

       num = Customer::numType;
       Customer::numType++;     
     
     customerList[customerTotal] = *new Customer(customerID,firstName,lastName,address,phoneNum,type);
      customerTotal++;
     
   customers.close();
}

void DisplayCustomer(Customer customerList[])
{
   int num = Customer::numType;

   cout << "===================================" << endl;
   cout << "*** Overall Customer Statistics ***" << endl;          
   cout << "Number of customers type Normal: " << num << endl;        
   cout << "Number of customers type Silver: " << num << endl;      
   cout << "Number of customers type Gold: " << num << endl;    
   cout << "Number of customers type Platinum: " << num << endl;        
   cout << "Total number of customers: " << num << endl;
   cout << endl;
   
}


Answer
Hello Lisa.

Please make sure you read my suggestion at the end before making changes to your code.


Here are the problems I found:
============================================================================
First lets correct the syntax errors. In many places you have a string that spans multiple lines. For example:

case Normal:   cout << "Normal
";
         break;

You see how the ending quote is on a different line from the starting quote. Did you do that or did the AllExperts web site make it that way?

The correction looks like this:
case Normal:   cout << "Normal";
         break;

After I corrected those errors, my compiler told me that the next error is in the main function, where you are doing:
  customerList[customerTotal] = *new Customer(customerID,firstName,lastName,address,phoneNum,type);

You are trying to call a Customer constructor with 6 arguments, but you do not have such a constructor. The constructor should look much like your setCustomer method. Can you make such a constructor on your own?

Where are you planning to read the file? You are no longer calling Customer::read. If you want to call a Customer constructor with the ID, name, address, etc, you will need to read those items in before calling the constructor.

I don't understand what Customer::numType is for. It seems to be the same as customerTotal.

You have this line:
customerList[customerTotal] = *new Customer(customerID,firstName,lastName,address,phoneNum,type);
in both main, and in readFile. You should make up your mind about which function will have the job of creating the customer.


My suggestion:
============================================================================
I would suggest that you forget about the 6 argument Customer constructor, and go back to the Customer::read method. The previous version of the program I sent you was almost working. Simply do this:

  int customerTotal = 0;
  Customer c;
  while (!customers.eof())
  {
      if (c.read(customers))
      {
         customerList[customerTotal++] = c;
      }
  }

The customer c will be copied into the array. There is no need to do a "new" here. Also, in case you're wondering about copy constructors, you do not need a copy constructor here. The copy will be done automatically.

Once you have the customers in the array, go over the array again and count the number of customers of each type.

Print out the number of customers of each type, then go over the array again and print out the individual customers.

Then go on to do the bank accounts and investment accounts.




======================================================================================
======================================================================================
Edit November 9, 8:00 EST
======================================================================================
======================================================================================

Hello Lisa. I hope I haven't frustrated you. If I've confused you, I am sorry. I am trying to guide you through the process of learning how to solve these problems yourself. If you do not learn for yourself, you will have trouble on your exams. However, I do remember what it's like to be a student, and I know you have many pressures. So, I am going to give a working solution to you assignment. It will be up to your to test it with your files, and to format the output the way you want it. I am using vectors, instead of arrays to store customers, accounts, and investments. If you have any questions, please ask.

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
#include <sstream>
#include <vector>

using namespace std;

bool allDigits(const string& input)
{
   for(size_t ix = 0; ix < input.size(); ++ix)
   {
       if (!isdigit(input[ix])) return false;
   }
   return true;
}

void toLowerCase(string& input)
{
   for(size_t ix = 0; ix < input.size(); ++ix) input[ix] = tolower(input[ix]);
}


class Customer
{
public:
   enum CustomerType
   {
       Normal = 1,
       Gold,
       Silver,
       Platinum
   };

   Customer () {}
   void setCustomer(int, string, string, string, int, CustomerType);
   void display();
   bool read(ifstream& fin);
   CustomerType getType(void) const { return type; }

private:
   int customerID;
   string firstName;
   string lastName;
   string address;
   int phoneNum;
   CustomerType type;

   static const int ID_LENGTH = 5;
   static const int PHONE_LENGTH = 8;
};

class Account
{
public:
   enum AccountType
   {
       Savings = 1,
       Checkings,
       FixedDeposit
   };

   Account () {}
   void setAccount(int, int, AccountType, int, int);
   void display();
   bool read(ifstream& fin);

private:
   int customerID;
   int accountNum;
   int balance;
   int numYears;
   AccountType type;

   static const int ID_LENGTH = 5;
   static const int ACCOUNT_LENGTH = 6;

};

class Investment
{
public:
   enum InvestmentType
   {
       Stock = 1,
       RealEstate
   };

   Investment () {}
   void setInvestment(int, int, InvestmentType, int, int);
   void display();
   bool read(ifstream& fin);

private:
   int customerID;
   int investNum;
   int investValue;
   int currValue;
   InvestmentType type;

   static const int ID_LENGTH = 5;
   static const int INVESTNUM_LENGTH = 7;

};


void Customer::setCustomer(int id, string fn, string ln, string a, int pn, CustomerType t)
{
   customerID = id;
   firstName = fn;
   lastName = ln;
   address = a;
   phoneNum = pn;
   type = t;
}

void Customer::display()
{
   cout << "*** Individual Customer Statistics ***\n";
   cout << "*** Customer Particulars ***" << endl;
   cout << customerID << ' ' << firstName << "     " << lastName
       << "       " << address << "       " << phoneNum << "      " << type << endl;
}

bool Customer::read(ifstream& fin)
{
   // First read individual strings from the file
   string idText;
   string firstNameText;
   string lastNameText;
   string addressText;
   string phoneText;
   string typeText;


   // Read the entire line in, then create a string stream from the line.
   // The string stream will break the line down into its pieces.
   string line;
   getline(fin, line);
   istringstream ss (line);
   ss >> idText >> firstNameText >> lastNameText >> addressText >> phoneText >> typeText;


   // Now check that each input is valid

   // Check ID
   if (idText.length() != ID_LENGTH || !allDigits(idText)) return false;

   // Check names
   if (firstNameText.length() == 0) return false;
   if (lastNameText.length() == 0) return false;

   // Check address
   if (addressText.length() == 0) return false;

   // Check phone
   if (phoneText.length() != PHONE_LENGTH || !allDigits(phoneText)) return false;

   // Check customer type
   CustomerType inputType;
   toLowerCase(typeText);
   if (strcmp(typeText.c_str(), "normal") == 0) inputType = Normal;
   else if (strcmp(typeText.c_str(), "gold") == 0) inputType = Gold;
   else if (strcmp(typeText.c_str(), "silver") == 0) inputType = Silver;
   else if (strcmp(typeText.c_str(), "platinum") == 0) inputType = Platinum;
   else return false;

   // Now assign all inputs to the customer
   setCustomer(atoi(idText.c_str()),
       firstNameText,
       lastNameText,
       addressText,
       atoi(phoneText.c_str()),
       inputType);
   return true;
}

void Account::setAccount(int id, int an, AccountType t, int bl, int ny)
{
   customerID = id;
   accountNum = an;
   balance = bl;
   numYears = ny;
   type = t;
}

void Account::display()
{
   cout << "*** Bank accounts ***      " << endl;
   cout << customerID << ' ' << accountNum << "    " << type << "  " << balance << "       " << numYears << endl;
}

bool Account::read(ifstream& fin)
{
   // First read individual data from the file
   string idText;
   string accountNumText;
   string typeText;
   string balanceText;
   string numYearsText;



   // Read the entire line in, then create a string stream from the line.
   // The string stream will break the line down into its pieces.
   string line;
   getline(fin, line);
   istringstream ss (line);
   ss >> idText >> accountNumText >> typeText >> balanceText >> numYearsText;


   // Now check that each input is valid

   // Check ID
   if (idText.length() != ID_LENGTH || !allDigits(idText)) return false;

   // Check AccountNum
   if (accountNumText.length() != ACCOUNT_LENGTH || !allDigits(accountNumText)) return false;

   // Check account type
   AccountType inputType;
   toLowerCase(typeText);
   if (strcmp(typeText.c_str(), "savings") == 0) inputType = Savings;
   else if (strcmp(typeText.c_str(), "checkings") == 0) inputType = Checkings;
   else if (strcmp(typeText.c_str(), "fixed deposit") == 0) inputType = FixedDeposit;
   else return false;

   // Check balance
   if (balanceText.length() == 0) return false;

   // Check years
   if (numYearsText.length() == 0) return false;

   // Now assign all inputs to the account
   setAccount(atoi(idText.c_str()),
       atoi(accountNumText.c_str()),
       inputType,
       atoi(balanceText.c_str()),
       atoi(numYearsText.c_str()));
   return true;

}


void Investment::setInvestment(int id, int in, InvestmentType t, int iv, int cv)
{
   customerID = id;
   investNum = in;
   investValue = iv;
   currValue = cv;
   type = t;
}

void Investment::display()
{
   cout << "*** Investments ***      " << endl;
   cout << customerID << ' ' << investNum << "     " << type << "  " << investValue << "   " << currValue << endl;
}

bool Investment::read(ifstream& fin)
{
   // First read individual data from the file
   string idText;
   string investNumText;
   string typeText;
   string investValueText;
   string currValueText;



   // Read the entire line in, then create a string stream from the line.
   // The string stream will break the line down into its pieces.
   string line;
   getline(fin, line);
   istringstream ss (line);
   ss >> idText >> investNumText >> typeText >> investValueText >> currValueText;


   // Now check that each input is valid

   // Check ID
   if (idText.length() != ID_LENGTH || !allDigits(idText)) return false;

   // Check AccountNum
   if (investNumText.length() != INVESTNUM_LENGTH || !allDigits(investNumText)) return false;

   // Check account type
   InvestmentType inputType;
   toLowerCase(typeText);
   if (strcmp(typeText.c_str(), "stock") == 0) inputType = Stock;
   else if (strcmp(typeText.c_str(), "realestate") == 0) inputType =  RealEstate;
   else return false;

   // Check invest value
   if (investValueText.length() == 0) return false;

   // Check current value
   if (currValueText.length() == 0) return false;

   // Now assign all inputs to the investment
   setInvestment(atoi(idText.c_str()),
       atoi(investNumText.c_str()),
       inputType,
       atoi(investValueText.c_str()),
       atoi(currValueText.c_str()));
   return true;


}


int main()
{
   ////////////////////////////////////////////////////////
   // Open files
   ////////////////////////////////////////////////////////

   ifstream customerFile("customers.txt");
   ifstream accountFile("account.txt");
   ifstream investmentFile("investment.txt");

   if (!customerFile.is_open())
   {
       cout << "Error opening customer file";
       exit (1);
   }

   if (!customerFile.is_open())
   {
       cout << "Error opening accounts file";
       exit (1);
   }

   if (!investmentFile.is_open())
   {
       cout << "Error opening investments file";
       exit (1);
   }

   ////////////////////////////////////////////////////////
   // Read in files
   ////////////////////////////////////////////////////////

   vector<Customer> customers;
   vector<Account> accounts;
   vector<Investment> investments;

   Customer c;
   while (!customerFile.eof())
   {
       if (c.read(customerFile)) customers.push_back(c);
   }

   Account a;
   while (!customerFile.eof())
   {
       if (a.read(customerFile)) accounts.push_back(a);
   }

   Investment i;
   while (!investmentFile.eof())
   {
       if (i.read(investmentFile)) investments.push_back(i);
   }

   ////////////////////////////////////////////////////////
   // Print out overall statistics
   ////////////////////////////////////////////////////////
   int gold = 0;
   int platinum = 0;
   int silver = 0;
   int normal = 0;
   for (size_t i = 0; i < customers.size(); ++i)
   {
       switch(customers[i].getType())
       {
       case Customer::Gold: ++gold; break;
       case Customer::Platinum: ++platinum; break;
       case Customer::Silver: ++silver; break;
       case Customer::Normal: ++normal; break;
       }
   }
   cout << "*** Overall Customer Statistics ***\n";
   cout << "Number of customers type Normal: " << normal << endl;
   cout << "Number of customers type Gold: " << gold << endl;
   cout << "Number of customers type Platinim: " << platinum << endl;
   cout << "Number of customers type Silver: " << silver << endl;

   cout << endl;

   ////////////////////////////////////////////////////////
   // Print out individual customers
   ////////////////////////////////////////////////////////
   for (size_t i = 0; i < customers.size(); ++i)
   {
       customers[i].display();
   }

   ////////////////////////////////////////////////////////
   // Print out bank accounts
   ////////////////////////////////////////////////////////
   for (size_t i = 0; i < accounts.size(); ++i)
   {
       accounts[i].display();
   }

   ////////////////////////////////////////////////////////
   // Print out investment accounts
   ////////////////////////////////////////////////////////
   for (size_t i = 0; i < investments.size(); ++i)
   {
       investments[i].display();
   }
   return 0;
}

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Zlatko

Expertise

No longer taking questions.

Experience

No longer taking questions.

Education/Credentials
No longer taking questions.

©2016 About.com. All rights reserved.