Link to home
Start Free TrialLog in
Avatar of RySk8er30
RySk8er30

asked on

Accessing Data From a File

Hi,

I have a program which loads transactions from a file.  I have two classes Account and TransRecords.  The program starts with currAcct.verifyAccount();  Here is the account class:

/*

  Programmer; Ryan Zaleski
  Instructor: Mr. Paul Zanolli
  Course: CS121
  Date: April 5, 2004
  ADT Name: Account
  ADT File: Account.cpp
  Data Elements: see below for description
  Structure:
  Purpose: To hold current account infomation
  Other Classes Used:
  Data members: see below for description
  Member Functions: see below for description

*/

#include "Utility.h" //used for lower(), pause(), getPin(), center(), getNumOnly()
#include <fstream.h> //used for ifstream()
#include <iomanip.h> //used for setw()
#include "TransRecords.h" //used for transaction log

class Account { //Handles all account related activites

public:
      Account(); //Constructor
      Account(int acctNum, double balance, char *firstName, char *middleInital, char *lastName, int pin, char *acctFile); //Overloaded Constructor
      ~Account(); //Destructor
      Account(Account &p); //Copy Constructor
      void verifyAcct(); //Verifies account
      void displayAcctInfo(); //Displays account information to the user
      void displayTransHistory(); //Displays user's transaction history
      void serviceFeeCharge(int serviceFee); //Subtracts a service fee for withdrawals
      void makeDeposit(); //Makes a deposit into the account
      void makeWithdrawal(); //Takes a withdrawal from the account
      void saveInfo(); //Saves information to a file
      void changePin(); //Changes pin
      void displayMenu(); //Displays menu
      int menuOptions(); //Outputs menu choices

private:
      int acctNum; //Holds account number
      double balance; //Holds balance
      char firstName[PER_STR]; //Holds first name
      char middleInital; //Holds middle inital
      char lastName[PER_STR]; //Holds last name
      int pin; //Holds secret pin
      char acctFile[PER_STR]; //Holds account file name
      TransRecords transRecords[MAX_TRANS_RECORDS];
      int transRecordsSize;

}; //End Class Account declaration

Account::Account() { //Constructor
      
      /*

      Function Name: Account()
      Purpose: Constructor for account
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: void
      Data Members Accessed: acctNum, balance, firstName, middleInital, lastName, pin, acctFile
      Data Members Modified: acctNum, balance, firstName, middleInital, lastName, pin, acctFile
      Non-local Variables Used: none
      Functions Called: none

      */
      
      //Sets information to default values
      
      acctNum = 0;
      balance = 0;
      firstName[PER_STR] = '\0';
      middleInital = ' ';
      lastName[PER_STR] = '\0';
      pin = 0;
      acctFile[PER_STR] = '\0';
      transRecordsSize = 0;

} //End Constructor

Account::Account(int acctNum, double balance, char *firstName, char *middleInital, char *lastName, int pin, char *acctFile) { //Overlaoded Constructor

      /*

      Function Name: Account()
      Purpose: Overlaoded constructor for account
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: void
      Data Members Accessed: acctNum, balance, firstName, middleInital, lastName, pin, acctFile
      Data Members Modified: acctNum, balance, firstName, middleInital, lastName, pin, acctFile
      Non-local Variables Used: none
      Functions Called: none

      */
      
      //Sets information to given values
      
      acctNum = acctNum;
      balance = balance;
      firstName = firstName;
      middleInital = middleInital;
      lastName = lastName;
      pin = pin;
      acctFile = acctFile;

} //End Overloaded Constructor

Account::Account(Account &p) { //Copy Constructor

      /*

      Function Name: Account()
      Purpose: Copy Constructor for account
      Parameters:
            Input: none
            Input & Output: Account &p
            Output: none
      Return Value: void
      Data Members Accessed: acctNum, balance, firstName, middleInital, lastName, pin, acctFile
      Data Members Modified:
      Non-local Variables Used: none
      Functions Called: none

      */
      
      //Copies class to a new class
      
      p.acctNum = acctNum;
      p.balance = balance;
      p.firstName[PER_STR] = firstName[PER_STR];
      p.middleInital = middleInital;
      p.lastName[PER_STR] = lastName[PER_STR];
      p.pin = pin;
      p.acctFile[PER_STR] = acctFile[PER_STR];

} //End Copy Constructor

Account::~Account() { //Destructor

      /*

      Function Name: Account()
      Purpose: Destructor for account
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: void
      Data Members Accessed: acctNum, balance, firstName, middleInital, lastName, pin, acctFile
      Data Members Modified: acctNum, balance, firstName, middleInital, lastName, pin, acctFile
      Non-local Variables Used: none
      Functions Called: none

      */

} //End Destructor

void Account::verifyAcct() {  //Verifies account information

      /*

      Function Name: verifyAccount()
      Purpose: Verifies account information
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: void
      Data Members Accessed: acctNum, balance, firstName, middleInital, lastName, pin, acctFile
      Data Members Modified: acctNum, balance, firstName, middleInital, lastName, pin, acctFile
      Non-local Variables Used: none
      Functions Called: lower(), center(), getNumOnly(), getPin(), pause()

      */
      
      //Local Variables
      bool exit = false; //used to exit loop
      int pinFile = 0; //sets default pinFile number
      double transAmt = 0;
      int transType = 0;
      double endingBalance = 0;
      char temp;
      int i = 0;

      do {

      //prompts user for account number/pin, gets account number/pin

      lower();
      center("Please enter your four digit account number: ");
      cout << endl << setw(37) << " ";
      acctNum = getNumOnly();
      cout << endl << endl;
      center("Please enter your four digit pin number: ");
      cout << endl << setw(37) << " ";
      pin = getPin();

      _itoa(acctNum, acctFile, 10); //Puts value of acctNum into acctFile (and converts to string)

      strcat(acctFile, ".txt"); //Adds ".txt" to string

      ifstream infile; //Creates infile

      //Tries to open the file.  If it does not exist, it does not create one.
      infile.open(acctFile, ios::in|ios::nocreate);
      
      //If the account does not exist, output "Invalid account number..."
      
      if (!infile) {

            ClearScreen;
            lower();
            center("Invalid account number...");
            cout << endl << endl;
            pause();
            ClearScreen;

      } else { //Input information

            infile >> acctNum;
            infile >> balance;
            infile >> pinFile;
            infile >> firstName;
            infile >> middleInital;
            infile >> lastName;
            infile >> temp;

            infile >> transAmt;

            while (!infile.eof() && transAmt != 0) {
                  
                  infile >> transType;
                  infile >> endingBalance;
                  infile >> temp;

                  transRecords[i].addRecord(transAmt, transType, endingBalance);
                  pause();
                  i++;

                  infile >> transAmt;
      }
            //Closes the file
            infile.close();

            transRecordsSize = i;

            if (pinFile != pin) { //If pin does not match file's pin, output "Invalid pin number..."

                  ClearScreen;
                  lower();
                  center("Invalid pin number...");
                  cout << endl << endl;
                  pause();
                  ClearScreen;

            } else { //If pin matches exit loop
                  
                  exit = true;

            }      

      }

      } while (!exit); //end loop

} //end verifyAccount()

void Account::displayAcctInfo(){ //Displays account information to the user
      
      /*

      Function Name: displayAcctInfo
      Purpose: To display current account information
      Parameters:
            Input: none
            Input & Output: none
            Output: acctNum, balance, firstName, lastName
      Return Value: void
      Data Members Accessed: acctNum, balance, firstName, lastName
      Data Members Modified: none
      Non-local Variables Used: none
      Functions Called: lower(), center(), pause()

      */
      
      //Outputs information to user
      system("cls");
      lower();
      center("Account Information:");
      cout << endl;
      cout << setw(39) << "Name: " << firstName << " " << middleInital << " " << lastName << endl;
      cout << setw(39) << "Account Number: " << acctNum << endl;
      cout << setw(39) << "Balance Amount: " << setiosflags(ios::fixed) << setprecision(2) << balance << endl << endl;
      pause();
      ClearScreen;

} //End displayAcctInfo

void Account::serviceFeeCharge(int serviceFee){ //Adds a service fee for withdrawals

      /*

      Function Name: serviceFeeCharge
      Purpose: To subtract a service fee charge to balance
      Parameters:
            Input: serviceFee
            Input & Output: none
            Output: none
      Return Value: void
      Data Members Accessed: balance
      Data Members Modified: none
      Non-local Variables Used: none
      Functions Called: none

      */
      
      //Subtracts service fee from balance
      balance = balance - serviceFee;

} //End serviceFeeCharge Function

void Account::makeDeposit(){ //Makes a deposit into the account

      /*

      Function Name: makeDeposit
      Purpose: To input a deposit
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: void
      Data Members Accessed: balance
      Data Members Modified: none
      Non-local Variables Used: none
      Functions Called: getCurr(), lower(), center(), pause()

      */

      //Local Variables
      double transAmt = 0; //Holds transaction amount

      //Asks for a despoit amount, if amount is not valid, -1 is returned and user is prompted again
      do {

            if (transAmt < 0) {

                  lower();
                  center("Invalid amount.");
                  cout << endl;
                  pause();

            }

            ClearScreen;
            lower();
            center("Please enter a deposit amount: ");
            cout << endl << setw(37) << " ";
            transAmt = getCurr();
            ClearScreen;

      } while (transAmt < 0);

      //Increases balance by transaction amount
      balance += transAmt;

      transRecords[transRecordsSize].addRecord(transAmt, 1, balance);

      ++transRecordsSize;

      //Displays balance and transaction amount.

      lower();
      cout << "                         " << "Thank you for your deposit of " << setiosflags(ios::fixed) << setprecision(2) << transAmt << endl;
      cout << endl;
      cout << "                         " << "    Your balance is " << setiosflags(ios::fixed) << setprecision(2) << balance << "\n" << endl;
      pause();
      ClearScreen;

} //End makeDeposit Function

void Account::makeWithdrawal(){ //Takes a withdrawal from the account

      /*

      Function Name: makeWithdrawal
      Purpose: To subtract a withdrawal from the balance
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: void
      Data Members Accessed: balance
      Data Members Modified: none
      Non-local Variables Used: none
      Functions Called: getCurr(), serviceFeeCharged, lower(), center(), pause()

      */
      
      //Local Variables
      int serviceFee = 1; //serviceFee holds charge for making a withdrawal
      double transAmt = 0; //transAmt holds the transaction amount
      char agree; //agree holds a y or n value to confirm if user wants to continue or not after viewing the service fee

      //Lets user know there is a service fee, if they agree you continue.

      ClearScreen;
      lower();
      cout << "                        " << "There will be a $" << serviceFee << " service charge." << endl;
      cout << endl;
      cout << "                         " << "Do you wish to continue, y or n: " << endl;
      cout << endl;
      cout << setw(39) << " ";
      agree = getYN();

      if (agree == 'y') { //If agree = y, then it prompts user for withdrawal amount

            //Asks for a despoit amount, if amount is not valid, -1 is returned and user is prompted again
            do {

                  if (transAmt < 0) {

                        ClearScreen;
                        lower();
                        center("Invalid amount.");
                        cout << endl;
                        pause();

                  }

                  //Prompt for withdrawal amount

                  ClearScreen;
                  lower();
                  center("Please enter a withdrawal amount: ");
                  cout << endl << setw(37) << " ";
                  transAmt = getCurr();

            } while (transAmt < 0); //end loop

            ClearScreen;

            if (transAmt > (balance - serviceFee)) {

                  //If they choose to extract more money than they have they recieve an error, and no money is taken out.

                  lower();
                  cout << "                " << "Your withdrawal amount exceeds your balance of $";
                  cout << setiosflags(ios::fixed) << setprecision(2) << balance << "." << endl << endl;
                  center("No withdrawal has been made.");
                  cout << endl;
                  pause();
                  ClearScreen;

            } else {

            //Transaction amount is subtracted from balance.
                  
            balance -= transAmt;

            //Charges service fee
            serviceFeeCharge(serviceFee);

            transRecords[transRecordsSize].addRecord(transAmt, 0, balance);

            ++transRecordsSize;

            //Displays the current balance, and transaction amount.

            lower();
            cout << "                            " << "Here is your " << setiosflags(ios::fixed) << setprecision(2) << transAmt << " withdrawal." << endl;
            cout << endl;
            cout << "                              " << "Your balance is " << setiosflags(ios::fixed) << setprecision(2) << balance << "\n" << endl;
            pause();
            ClearScreen;
            
            }

      } else {

            //Does not make a withdrawal if the user declines service fee.

            ClearScreen;
            lower();
            center("No withdrawal has been made.");
            cout << endl;
            pause();
            ClearScreen;
      }

} //End withdrawal Function

void Account::saveInfo(){ //Saves information to a file

      /*

      Function Name: saveInfo
      Purpose: To save the information to a file.
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: void
      Data Members Accessed: balance, acctNum, firstName, lastName, middleInital, pin
      Data Members Modified: balance, acctNum, firstName, lastName, middleInital, pin
      Non-local Variables Used: none
      Functions Called: none

      */

      //Writes information to a file named "1234.txt"
      ofstream outfile("1234.txt", ios::out);
      outfile << acctNum << endl;
      outfile << balance << endl;
      outfile << pin << endl;
      outfile << firstName << endl;
      outfile << middleInital << endl;
      outfile << lastName << endl;
      outfile << "*" << endl;

      for (int i = 0; i < transRecordsSize; i++) {
            outfile << transRecords[i].getTransAmt() << endl;
            outfile << transRecords[i].getTransType() << endl;
            outfile << transRecords[i].getEndingBalance() << endl;
            outfile << "*" << endl;
      }

      outfile.close();

} //End saveInfo

void Account::changePin() { //Changes pin

      /*

      Function Name: changePin
      Purpose: Changes user's pin
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: void
      Data Members Accessed: pin
      Data Members Modified: pin
      Non-local Variables Used: none
      Functions Called: lower(), center(), getPin()

      */

      //prompts for new pin

      ClearScreen;
      lower();
      center("Please enter your new pin number: ");
      cout << endl << setw(38) << " ";
      pin = getPin();

} //End changePin

void Account::displayMenu() {

      /*

      Function Name: displayMenu()
      Purpose: Displays menu
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: void
      Data Members Accessed: none
      Data Members Modified: none
      Non-local Variables Used: none
      Functions Called: menuOptions(), displayAcctInfo(), saveInfo(), makeDeposit(), makeWithdrawal(), changePin(), lower(), center(), pause()

      */
      
      //Local Variables
      bool exit = false; //Set to false until a valid menu option is choosen.

      ClearScreen;
      
      do { //Loops through the menu options until a user chooses one.
            switch (Account::menuOptions()) {
                  
            case 1: //Display account information
                  displayAcctInfo();
                  //currAcct.displayAcctInfo();
                  break;
            case 2: //Make a deposit and saves changes
                  makeDeposit();
                  saveInfo();
                  break;
            case 3: //Make a withdrawal and saves changes
                  makeWithdrawal();
                  saveInfo();
                  break;
            case 4: //Display transaction history
                  displayTransHistory();
                  break;
            case 5: //Change pin and save changes
                  changePin();
                  saveInfo();
                  break;
            case 6: //Exit
                  exit = true;
                  break;
            default: //Prompts user to try again
                  ClearScreen;
                  lower();
                  center("Invalid input.");
                  cout << endl;
                  pause();
                  exit = false;
                  break;
            }
      } while (!exit); //Loops through the menu options until a user chooses one.

}

int Account::menuOptions() { //Prints out menu options to user

      /*

      Function Name: menuOptions
      Purpose: To display menu options to the user
      Parameters:
            Input: none
            Input & Output: none
            Output: choice
      Return Value: int
      Data Members Accessed: none
      Data Members Modified: none
      Non-local Variables Used: none
      Functions Called: lower(), center(), menuChoice()

      */
      
      //Local Variables
      int choice; //Holds the menu option choice

      ClearScreen;
      
      //Displays menu options to user
      lower();
      center("Please select from the following options:");
      cout << endl;
      cout << "                        " << "1) Display account information" << endl
             << "                        " << "2) Make a deposit" << endl
             << "                        " << "3) Make a withdrawal" << endl
             << "                        " << "4) Display transaction history" << endl
             << "                        " << "5) Change pin" << endl
             << "                        " << "6) Exit" << endl;

      cout << endl << setw(39) << " ";

      //sets return value of menuChoice() to choice
      choice = menuChoice();

      return choice;

} //End menuOptions Function

void Account::displayTransHistory() {

      ClearScreen;

      cout << "Transaction Log" << endl;

      for (int i = 0; i < transRecordsSize; i++) {
            transRecords[i].displayRecords();
      }

      pause();

}


Here is the TransRecords class...

#include <iostream.h>
#include "Time.h"

class TransRecords {

public:
      TransRecords();
      ~TransRecords();
      void addRecord(double newTransAmt, int newTransType, double newEndingBalance);
      void displayRecords();
      double getTransAmt();
      int getTransType();
      double getEndingBalance();

private:
      double transAmt;
      int transType;
      double endingBalance;
      char time[7];

};

TransRecords::TransRecords() { //Constructor

      transAmt = 0;
      transType = 0;
      endingBalance = 0;
      time[7] = '\0';

}

TransRecords::~TransRecords() { //Destructor

}

void TransRecords::addRecord(double newTransAmt, int newTransType, double newEndingBalance) {
      
      Time t;
      char *temp = time;

      temp = t.getTimeCode();
      
      transAmt = newTransAmt;
      transType = newTransType;
      endingBalance = newEndingBalance;
      
}

void TransRecords::displayRecords() {

      cout << transAmt << endl;

      if (transType == 1) {
            cout << "Deposit" << endl;
      } else {
            if (transType == 0) {
                  cout << "Withdrawal" << endl;
            } else {
                  cout << "Error" << endl;
            }
      }

      cout << endingBalance << endl;
      //cout << time << endl;
      cout << endl;

}

double TransRecords::getTransAmt() {

      return transAmt;

}

int TransRecords::getTransType() {

      return transType;

}

double TransRecords::getEndingBalance() {
      
      return endingBalance;

}


When I try to display the transaction records my data comes back with 0's, but there is data in my files.  If I cout the transAmt for example in verifyAcct, it outputs the correct value.  If I cout it in addRecord it works, but if I cout it in displayRecords, I get a zero.  Any ideas?

Ryan

Avatar of wayside
wayside

I don't see anything obvious... I can't compile it though, you didn't include everything needed. Maybe you could post the rest of it.

Try setting the values in the constructor for TransRecords to something other than 0, like 1234.567, that way if these values get printed you know the problem is somewhere in updating these records.

Other than that... time to get very familiar with the debugger. ;)

What compiler are you using?
Avatar of Axter
>>time to get very familiar with the debugger. ;)

I second that....

Put break points in your code, where it should be reading in the data, and find out what's going on.
Avatar of RySk8er30

ASKER

Hi,

I'm using Microsoft Visual C++ 6.0.  It seems like the problem is here...

void TransRecords::addRecord(double newTransAmt, int newTransType, double newEndingBalance) {
      
      Time t;
      char *temp = time;

      temp = t.getTimeCode();
      
      cout << transAmt << endl;
      transAmt = newTransAmt;
      transType = newTransType;
      endingBalance = newEndingBalance;
      cout << transAmt << endl;
      
}

The first cout produces garbage.  The second one produces the correct value.  Then after I call that if I call this...

double TransRecords::getTransAmt() {

      return transAmt;

}

That returns the value that was created in the constructor.

Ryan
The following section of code can produce undefined behavior.
    Time t;
     char *temp = time;

     temp = t.getTimeCode();
What is "time" in your code?
Hi,

Don't worry about that section of code.  That is not the problem right now.  For some reason the assignment here...

void TransRecords::addRecord(double newTransAmt, int newTransType, double newEndingBalance) {
      
      Time t;
      char *temp = time;

      temp = t.getTimeCode();
      
      cout << transAmt << endl;
      transAmt = newTransAmt;
      transType = newTransType;
      endingBalance = newEndingBalance;
      cout << transAmt << endl;
      
}

...is only changing for the scope of the member function, not the class.  Any ideas?

Ryan
>>...is only changing for the scope of the member function, not the class.  Any ideas?

How do you know that?

Your code is display the values before they're getting set.
   cout << transAmt << endl;
   transAmt = newTransAmt;
I believe the above should be the following:
     transAmt = newTransAmt;
     cout << transAmt << endl;

Disregard previous comment.
I misread your code.

Are you saying after this function is called, that when you call getTransAmt() it does not return the value that was set?
This...

void TransRecords::addRecord(double newTransAmt, int newTransType, double newEndingBalance) {
     
     Time t;
     char *temp = time;

     temp = t.getTimeCode();
     
     cout << transAmt << endl;
     transAmt = newTransAmt;
     transType = newTransType;
     endingBalance = newEndingBalance;
     cout << transAmt << endl;
     
}

Outputs garbage from the first cout, then the proper number from the second.  Then when I run this accessor function...

double TransRecords::getTransAmt() {

      return transAmt;

}

I get the value that the constructor sets.  Shouldn't the first cout show this same value, not garbage?  And shouldn't this value show the proper number?

Ryan
>>I get the value that the constructor sets.  Shouldn't the first cout show this same value, not garbage?  And
>>shouldn't this value show the proper number?

Ahhh.... Now I understand the question.
I know you think the previous section of code has nothing to do with it, but you should try commenting it out, just to be sure.
Just because you're getting problems in one section of code, doesn't mean that it's not related to a completely unrelated section of code logic.
I also recommend you try creating a private copy constructor for TransRecords class, just to make sure you're not getting some values via compiler created copy constructor.
What he is saying is that it's preset in the contructor to 0.  so that first cout should show an intialized variable.

I'm curious, what does that getTimeCode method return exactly?  Is it bounds checked?
I guess, I'm unable to tell how you know that the transaction you changed is the one reset to 0.  Are they all reset to 0 when you save to a file or something, or just certain transactions?

Also, you should do more checking to make sure you never exceed max transations so you don't get out of bounds.
Hi,

Well I don't understand.  I removed those three lines of code:

Time t;
char *temp = time;
temp = t.getTimeCode();

and it worked.  The getTimeCode returns a pointer to the current time code (e.g. D44?:d0).  It is always 7 digits.  I want to write this to a file, but it won't work, so I tried to input it into a character array.  Any ideas on this?

Ryan
The first cout should be returning the value set by the constructor, not garbage. The fact that it doesn't is troublesome, and may mean you have a memory corruption somewhere.

Are you sure that the Time::getTimeCode() function returns only 6 bytes plus a NULL?

Although, this code:

    Time t;
     char *temp = time;

     temp = t.getTimeCode();
 
doesn't actually do anything; you set temp to point to time, and then you reset temp to point to the string returned by getTimeCode(). In order to get the time into the time[] array, you have to copy it in:

   strncpy(time, temp, 6);

D44?:d0

is seven characters, you have to allocate 7 plus 1 for the NULL, or 8 characters. You only allocate 7 characters.

And you still need to copy in to the array as I mention above.
>>and it worked.  The getTimeCode returns a pointer to the current time code (e.g. D44?:d0).  It is always 7
>>digits.  I want to write this to a file, but it won't work, so I tried to input it into a character array.  Any ideas on this?

You still have not explain what is time in your code.
Try this, and see if it works:
Time t;
     char *temp = NULL;

     temp = t.getTimeCode();
Axter,

time is:
char time[7];

Initialized to
time[7] = '\0';

Which is out of bounds.

When you declare an array, you declare the SIZE.  

When you use the array, you use the INDEX.  The index is 0-based.  The size is not.  0 size is not 1 :)  0 index is the first.
Time is a character array of 8 characters.  All I really want to do is be able to write t.getTimeCode() to a file, but I can't because it is a pointer.

Ryan
No, it's an array of 7 characters.
Hi,

It's now 8 characters, I changed it.  I tried this...

      Time t;

      strncpy(time, t.getTimeCode(), 8);

      cout << time;
      
      transAmt = newTransAmt;
      transType = newTransType;
      endingBalance = newEndingBalance;

But my transAmt, transType, and endingBalance get messed up again, but the time code couts fine.  

Ryan
Try this:

     strncpy(time, t.getTimeCode(), 7);
     time[7] = '\0';

This will guarantee that the time character array is properly terminated.

Hi,

Still no luck.  The time displays fine, but the numbers are still getting corrupt.

Ryan
Hrm.

Is it possible to zip up the project and put it somewhere?

Or post the missing pieces of code?
if we could see the getTimeCode body, it might be easier to tell where the corruption is coming from.
>>Time is a character array of 8 characters

If this is a character array of 8 characters, then you still don't have enough space for the following:
strncpy(time, t.getTimeCode(), 8);


The above line of code needs an array of 9 characters, which would include the \0 terminator.
Could you please post the implementation and/or the declaration for getTimeCode?
Hi,

When I try to view my transactions (from the menu).  I don't get proper values.  Here is all my code:

************************ACCOUNT.CPP *****************************

/*

  Programmer; Ryan Zaleski
  Instructor: Mr. Paul Zanolli
  Course: CS121
  Date: April 5, 2004
  ADT Name: Account
  ADT File: Account.cpp
  Data Elements: see below for description
  Structure:
  Purpose: To hold current account infomation
  Other Classes Used:
  Data members: see below for description
  Member Functions: see below for description

*/

#include "Utility.h" //used for lower(), pause(), getPin(), center(), getNumOnly()
#include <fstream.h> //used for ifstream()
#include <iomanip.h> //used for setw()
#include "TransRecords.h" //used for transaction log

class Account { //Handles all account related activites

public:
      Account(); //Constructor
      Account(int acctNum, double balance, char *firstName, char *middleInital, char *lastName, int pin, char *acctFile); //Overloaded Constructor
      ~Account(); //Destructor
      Account(Account &p); //Copy Constructor
      void verifyAcct(); //Verifies account
      void displayAcctInfo(); //Displays account information to the user
      void displayTransHistory(); //Displays user's transaction history
      void serviceFeeCharge(int serviceFee); //Subtracts a service fee for withdrawals
      void makeDeposit(); //Makes a deposit into the account
      void makeWithdrawal(); //Takes a withdrawal from the account
      void saveInfo(); //Saves information to a file
      void changePin(); //Changes pin
      void displayMenu(); //Displays menu
      int menuOptions(); //Outputs menu choices

private:
      int acctNum; //Holds account number
      double balance; //Holds balance
      char firstName[PER_STR]; //Holds first name
      char middleInital; //Holds middle inital
      char lastName[PER_STR]; //Holds last name
      int pin; //Holds secret pin
      char acctFile[PER_STR]; //Holds account file name
      TransRecords transRecords[MAX_TRANS_RECORDS];
      int transRecordsSize;

}; //End Class Account declaration

Account::Account() { //Constructor
      
      /*

      Function Name: Account()
      Purpose: Constructor for account
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: void
      Data Members Accessed: acctNum, balance, firstName, middleInital, lastName, pin, acctFile
      Data Members Modified: acctNum, balance, firstName, middleInital, lastName, pin, acctFile
      Non-local Variables Used: none
      Functions Called: none

      */
      
      //Sets information to default values
      
      acctNum = 0;
      balance = 0;
      firstName[PER_STR] = '\0';
      middleInital = ' ';
      lastName[PER_STR] = '\0';
      pin = 0;
      acctFile[PER_STR] = '\0';
      transRecordsSize = 0;

} //End Constructor

Account::Account(int acctNum, double balance, char *firstName, char *middleInital, char *lastName, int pin, char *acctFile) { //Overlaoded Constructor

      /*

      Function Name: Account()
      Purpose: Overlaoded constructor for account
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: void
      Data Members Accessed: acctNum, balance, firstName, middleInital, lastName, pin, acctFile
      Data Members Modified: acctNum, balance, firstName, middleInital, lastName, pin, acctFile
      Non-local Variables Used: none
      Functions Called: none

      */
      
      //Sets information to given values
      
      acctNum = acctNum;
      balance = balance;
      firstName = firstName;
      middleInital = middleInital;
      lastName = lastName;
      pin = pin;
      acctFile = acctFile;

} //End Overloaded Constructor

Account::Account(Account &p) { //Copy Constructor

      /*

      Function Name: Account()
      Purpose: Copy Constructor for account
      Parameters:
            Input: none
            Input & Output: Account &p
            Output: none
      Return Value: void
      Data Members Accessed: acctNum, balance, firstName, middleInital, lastName, pin, acctFile
      Data Members Modified:
      Non-local Variables Used: none
      Functions Called: none

      */
      
      //Copies class to a new class
      
      p.acctNum = acctNum;
      p.balance = balance;
      p.firstName[PER_STR] = firstName[PER_STR];
      p.middleInital = middleInital;
      p.lastName[PER_STR] = lastName[PER_STR];
      p.pin = pin;
      p.acctFile[PER_STR] = acctFile[PER_STR];

} //End Copy Constructor

Account::~Account() { //Destructor

      /*

      Function Name: Account()
      Purpose: Destructor for account
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: void
      Data Members Accessed: acctNum, balance, firstName, middleInital, lastName, pin, acctFile
      Data Members Modified: acctNum, balance, firstName, middleInital, lastName, pin, acctFile
      Non-local Variables Used: none
      Functions Called: none

      */

} //End Destructor

void Account::verifyAcct() {  //Verifies account information

      /*

      Function Name: verifyAccount()
      Purpose: Verifies account information
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: void
      Data Members Accessed: acctNum, balance, firstName, middleInital, lastName, pin, acctFile
      Data Members Modified: acctNum, balance, firstName, middleInital, lastName, pin, acctFile
      Non-local Variables Used: none
      Functions Called: lower(), center(), getNumOnly(), getPin(), pause()

      */
      
      //Local Variables
      bool exit = false; //used to exit loop
      int pinFile = 0; //sets default pinFile number
      double transAmt = 0;
      int transType = 0;
      double endingBalance = 0;
      char temp;
      int i = 0;
      char tempTime[8];

      do {

      //prompts user for account number/pin, gets account number/pin

      lower();
      center("Please enter your four digit account number: ");
      cout << endl << setw(37) << " ";
      acctNum = getNumOnly();
      cout << endl << endl;
      center("Please enter your four digit pin number: ");
      cout << endl << setw(37) << " ";
      pin = getPin();

      _itoa(acctNum, acctFile, 10); //Puts value of acctNum into acctFile (and converts to string)

      strcat(acctFile, ".txt"); //Adds ".txt" to string

      ifstream infile; //Creates infile

      //Tries to open the file.  If it does not exist, it does not create one.
      infile.open(acctFile, ios::in|ios::nocreate);
      
      //If the account does not exist, output "Invalid account number..."
      
      if (!infile) {

            ClearScreen;
            lower();
            center("Invalid account number...");
            cout << endl << endl;
            pause();
            ClearScreen;

      } else { //Input information

            infile >> acctNum;
            infile >> balance;
            infile >> pinFile;
            infile >> firstName;
            infile >> middleInital;
            infile >> lastName;
            infile >> temp;

            infile >> transAmt;

            while (!infile.eof() && transAmt != NULL) {
                  
                  infile >> transType;
                  infile >> endingBalance;
                  infile >> tempTime;
                  infile >> temp;

                  transRecords[i].loadRecord(transAmt, transType, endingBalance, tempTime);
                  i++;

                  infile >> transAmt;
      }
            //Closes the file
            infile.close();

            transRecordsSize = i;

            if (pinFile != pin) { //If pin does not match file's pin, output "Invalid pin number..."

                  ClearScreen;
                  lower();
                  center("Invalid pin number...");
                  cout << endl << endl;
                  pause();
                  ClearScreen;

            } else { //If pin matches exit loop
                  
                  exit = true;

            }      

      }

      } while (!exit); //end loop

} //end verifyAccount()

void Account::displayAcctInfo(){ //Displays account information to the user
      
      /*

      Function Name: displayAcctInfo
      Purpose: To display current account information
      Parameters:
            Input: none
            Input & Output: none
            Output: acctNum, balance, firstName, lastName
      Return Value: void
      Data Members Accessed: acctNum, balance, firstName, lastName
      Data Members Modified: none
      Non-local Variables Used: none
      Functions Called: lower(), center(), pause()

      */
      
      //Outputs information to user
      system("cls");
      lower();
      center("Account Information:");
      cout << endl;
      cout << setw(39) << "Name: " << firstName << " " << middleInital << " " << lastName << endl;
      cout << setw(39) << "Account Number: " << acctNum << endl;
      cout << setw(39) << "Balance Amount: " << setiosflags(ios::fixed) << setprecision(2) << balance << endl << endl;
      pause();
      ClearScreen;

} //End displayAcctInfo

void Account::serviceFeeCharge(int serviceFee){ //Adds a service fee for withdrawals

      /*

      Function Name: serviceFeeCharge
      Purpose: To subtract a service fee charge to balance
      Parameters:
            Input: serviceFee
            Input & Output: none
            Output: none
      Return Value: void
      Data Members Accessed: balance
      Data Members Modified: none
      Non-local Variables Used: none
      Functions Called: none

      */
      
      //Subtracts service fee from balance
      balance = balance - serviceFee;

} //End serviceFeeCharge Function

void Account::makeDeposit(){ //Makes a deposit into the account

      /*

      Function Name: makeDeposit
      Purpose: To input a deposit
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: void
      Data Members Accessed: balance
      Data Members Modified: none
      Non-local Variables Used: none
      Functions Called: getCurr(), lower(), center(), pause()

      */

      //Local Variables
      double transAmt = 0; //Holds transaction amount

      //Asks for a despoit amount, if amount is not valid, -1 is returned and user is prompted again
      do {

            if (transAmt < 0) {

                  lower();
                  center("Invalid amount.");
                  cout << endl;
                  pause();

            }

            ClearScreen;
            lower();
            center("Please enter a deposit amount: ");
            cout << endl << setw(37) << " ";
            transAmt = getCurr();
            ClearScreen;

      } while (transAmt < 0);

      //Increases balance by transaction amount
      balance += transAmt;

      transRecords[transRecordsSize].addRecord(transAmt, 1, balance);

      ++transRecordsSize;

      //Displays balance and transaction amount.

      lower();
      cout << "                         " << "Thank you for your deposit of " << setiosflags(ios::fixed) << setprecision(2) << transAmt << endl;
      cout << endl;
      cout << "                         " << "    Your balance is " << setiosflags(ios::fixed) << setprecision(2) << balance << "\n" << endl;
      pause();
      ClearScreen;

} //End makeDeposit Function

void Account::makeWithdrawal(){ //Takes a withdrawal from the account

      /*

      Function Name: makeWithdrawal
      Purpose: To subtract a withdrawal from the balance
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: void
      Data Members Accessed: balance
      Data Members Modified: none
      Non-local Variables Used: none
      Functions Called: getCurr(), serviceFeeCharged, lower(), center(), pause()

      */
      
      //Local Variables
      int serviceFee = 1; //serviceFee holds charge for making a withdrawal
      double transAmt = 0; //transAmt holds the transaction amount
      char agree; //agree holds a y or n value to confirm if user wants to continue or not after viewing the service fee

      //Lets user know there is a service fee, if they agree you continue.

      ClearScreen;
      lower();
      cout << "                        " << "There will be a $" << serviceFee << " service charge." << endl;
      cout << endl;
      cout << "                         " << "Do you wish to continue, y or n: " << endl;
      cout << endl;
      cout << setw(39) << " ";
      agree = getYN();

      if (agree == 'y') { //If agree = y, then it prompts user for withdrawal amount

            //Asks for a despoit amount, if amount is not valid, -1 is returned and user is prompted again
            do {

                  if (transAmt < 0) {

                        ClearScreen;
                        lower();
                        center("Invalid amount.");
                        cout << endl;
                        pause();

                  }

                  //Prompt for withdrawal amount

                  ClearScreen;
                  lower();
                  center("Please enter a withdrawal amount: ");
                  cout << endl << setw(37) << " ";
                  transAmt = getCurr();

            } while (transAmt < 0); //end loop

            ClearScreen;

            if (transAmt > (balance - serviceFee)) {

                  //If they choose to extract more money than they have they recieve an error, and no money is taken out.

                  lower();
                  cout << "                " << "Your withdrawal amount exceeds your balance of $";
                  cout << setiosflags(ios::fixed) << setprecision(2) << balance << "." << endl << endl;
                  center("No withdrawal has been made.");
                  cout << endl;
                  pause();
                  ClearScreen;

            } else {

            //Transaction amount is subtracted from balance.
                  
            balance -= transAmt;

            //Charges service fee
            serviceFeeCharge(serviceFee);

            transRecords[transRecordsSize].addRecord(transAmt, 0, balance);

            ++transRecordsSize;

            //Displays the current balance, and transaction amount.

            lower();
            cout << "                            " << "Here is your " << setiosflags(ios::fixed) << setprecision(2) << transAmt << " withdrawal." << endl;
            cout << endl;
            cout << "                              " << "Your balance is " << setiosflags(ios::fixed) << setprecision(2) << balance << "\n" << endl;
            pause();
            ClearScreen;
            
            }

      } else {

            //Does not make a withdrawal if the user declines service fee.

            ClearScreen;
            lower();
            center("No withdrawal has been made.");
            cout << endl;
            pause();
            ClearScreen;
      }

} //End withdrawal Function

void Account::saveInfo(){ //Saves information to a file

      /*

      Function Name: saveInfo
      Purpose: To save the information to a file.
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: void
      Data Members Accessed: balance, acctNum, firstName, lastName, middleInital, pin
      Data Members Modified: balance, acctNum, firstName, lastName, middleInital, pin
      Non-local Variables Used: none
      Functions Called: none

      */

      //Writes information to a file named "1234.txt"
      ofstream outfile("1234.txt", ios::out);
      outfile << acctNum << endl;
      outfile << balance << endl;
      outfile << pin << endl;
      outfile << firstName << endl;
      outfile << middleInital << endl;
      outfile << lastName << endl;
      outfile << "*" << endl;

      for (int i = 0; i < transRecordsSize; i++) {
            outfile << transRecords[i].getTransAmt() << endl;
            outfile << transRecords[i].getTransType() << endl;
            outfile << transRecords[i].getEndingBalance() << endl;
            outfile << transRecords[i].getTime() << endl;
            outfile << "*" << endl;
      }

      outfile.close();

} //End saveInfo

void Account::changePin() { //Changes pin

      /*

      Function Name: changePin
      Purpose: Changes user's pin
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: void
      Data Members Accessed: pin
      Data Members Modified: pin
      Non-local Variables Used: none
      Functions Called: lower(), center(), getPin()

      */

      //prompts for new pin

      ClearScreen;
      lower();
      center("Please enter your new pin number: ");
      cout << endl << setw(38) << " ";
      pin = getPin();

} //End changePin

void Account::displayMenu() {

      /*

      Function Name: displayMenu()
      Purpose: Displays menu
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: void
      Data Members Accessed: none
      Data Members Modified: none
      Non-local Variables Used: none
      Functions Called: menuOptions(), displayAcctInfo(), saveInfo(), makeDeposit(), makeWithdrawal(), changePin(), lower(), center(), pause()

      */
      
      //Local Variables
      bool exit = false; //Set to false until a valid menu option is choosen.

      ClearScreen;
      
      do { //Loops through the menu options until a user chooses one.
            switch (Account::menuOptions()) {
                  
            case 1: //Display account information
                  displayAcctInfo();
                  //currAcct.displayAcctInfo();
                  break;
            case 2: //Make a deposit and saves changes
                  makeDeposit();
                  saveInfo();
                  break;
            case 3: //Make a withdrawal and saves changes
                  makeWithdrawal();
                  saveInfo();
                  break;
            case 4: //Display transaction history
                  displayTransHistory();
                  break;
            case 5: //Change pin and save changes
                  changePin();
                  saveInfo();
                  break;
            case 6: //Exit
                  exit = true;
                  break;
            default: //Prompts user to try again
                  ClearScreen;
                  lower();
                  center("Invalid input.");
                  cout << endl;
                  pause();
                  exit = false;
                  break;
            }
      } while (!exit); //Loops through the menu options until a user chooses one.

}

int Account::menuOptions() { //Prints out menu options to user

      /*

      Function Name: menuOptions
      Purpose: To display menu options to the user
      Parameters:
            Input: none
            Input & Output: none
            Output: choice
      Return Value: int
      Data Members Accessed: none
      Data Members Modified: none
      Non-local Variables Used: none
      Functions Called: lower(), center(), menuChoice()

      */
      
      //Local Variables
      int choice; //Holds the menu option choice

      ClearScreen;
      
      //Displays menu options to user
      lower();
      center("Please select from the following options:");
      cout << endl;
      cout << "                        " << "1) Display account information" << endl
             << "                        " << "2) Make a deposit" << endl
             << "                        " << "3) Make a withdrawal" << endl
             << "                        " << "4) Display transaction history" << endl
             << "                        " << "5) Change pin" << endl
             << "                        " << "6) Exit" << endl;

      cout << endl << setw(39) << " ";

      //sets return value of menuChoice() to choice
      choice = menuChoice();

      return choice;

} //End menuOptions Function

void Account::displayTransHistory() {

      ClearScreen;

      cout << "Transaction Log" << endl;

      for (int i = 0; i < transRecordsSize; i++) {
            transRecords[i].displayRecords();
      }

      pause();

}

************************TRANSRECORDS.CPP *****************************

#include <iostream.h>
#include "Time.h"
#include <string.h>
#include <conio.h>

class TransRecords {

public:
      TransRecords();
      ~TransRecords();
      void addRecord(double newTransAmt, int newTransType, double newEndingBalance);
      void loadRecord(double newTransAmt, int newTransType, double newEndingBalance, char *newTime);
      void displayRecords();
      double getTransAmt();
      int getTransType();
      double getEndingBalance();
      char *getTime();

private:
      double transAmt;
      int transType;
      double endingBalance;
      Time time;

};

TransRecords::TransRecords() { //Constructor

      transAmt = 0;
      transType = 0;
      endingBalance = 0;

}

TransRecords::~TransRecords() { //Destructor

}

void TransRecords::addRecord(double newTransAmt, int newTransType, double newEndingBalance) {

      time.reset();
      transAmt = newTransAmt;
      transType = newTransType;
      endingBalance = newEndingBalance;
      
}

void TransRecords::loadRecord(double newTransAmt, int newTransType, double newEndingBalance, char *newTime) {
      
      Time t(newTime);
      time = t;

      transAmt = newTransAmt;
      transType = newTransType;
      endingBalance = newEndingBalance;

      cout << transAmt << " " << transType << " " << endingBalance << " " << time.getTimeCode() << " " << t.getTimeCode() << endl;
      
}

void TransRecords::displayRecords() {

      cout << transAmt << endl;

      if (transType == 1) {
            cout << "Deposit" << endl;
      } else {
            if (transType == 0) {
                  cout << "Withdrawal" << endl;
            } else {
                  cout << "Error" << endl;
            }
      }

      cout << endingBalance << endl;
      cout << getTime() << endl;
      cout << endl;

}

double TransRecords::getTransAmt() {

      return transAmt;

}

int TransRecords::getTransType() {

      return transType;

}

double TransRecords::getEndingBalance() {
      
      return endingBalance;

}

char *TransRecords::getTime() {
      
      return time.getTimeCode();

}


************************BANK.CPP *****************************

/*

  Programmer: Ryan Zaleski
  Instructor: Mr. Paul Zanolli
  Course: CS121
  Date: April 5, 2004
  Program Name: Bank
  Program File: Bank.cpp
  Input Files: 1234.txt
  Output Files: 1234.txt
  Modules Used: none
  Purpose: To act like an ATM.  Used to display account information, withdrawal money, deopsit money, change pin

*/

#include "Account.h" //used for Account Class
#include "Utility.h" //used for lower(), center() and pause()
#include <iomanip.h> //used for setw()

void main() {

      /*

      Function Name: main
      Purpose: Start point of program
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: void
      Data Members Accessed: none
      Data Members Modified: none
      Non-local Variables Used: none
      Functions Called: intro(), displayMenu(), exitScreen()

      */

      //Prototype Declarations
      void intro(); //Displays intro screen
      void displayMenu (Account currAcct); //Displays menu
      void exitScreen(); //Displays exit screen

      //Local Variables
      Account currAcct; //Used for current account
      Time time; //Used to display time
      bool exit = false; //Used to exit loop


      //Implementation
      do { //Continutously loops for user

            intro();
            currAcct.verifyAcct();
            currAcct.displayMenu();
            exitScreen();

      } while (!exit);

}

void intro() { //Function which prints introduction page.

      /*

      Function Name: Intro
      Purpose: To display an introduction page
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: void
      Data Members Accessed: none
      Data Members Modified: none
      Non-local Variables Used: none
      Functions Called: lower(), center(), pause()

      */

      //Local Variables
      Time t; //Used to display time
      
      lower();
      cout << CENTER << char(201) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(187) << endl;
      cout << CENTER << char(186) << "                                     " << char(186) << endl;
      cout << CENTER << char(186) << "        Welcome to Ryan's Bank       " << char(186) << endl;
      cout << CENTER << char(186) << "                                     " << char(186) << endl;
      cout << CENTER << char(186) << "           Do you trust me?          " << char(186) << endl;
      cout << CENTER << char(186) << "                                     " << char(186) << endl;
      cout << CENTER << char(200) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(188) << endl;
      cout << CENTER << endl;
      center(t.getDateAndTime());
      cout << endl;
      pause();

} //End intro Function

void exitScreen() { //Function which displays an exit screen

      /*

      Function Name: exitScreen
      Purpose: To display an exit screen
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: void
      Data Members Accessed: none
      Data Members Modified: none
      Non-local Variables Used: none
      Functions Called: lower(), pause()

      */

      //Writes an exit sreen
      ClearScreen;
      lower();
      cout << "                      " << char(201) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(187) << endl;
      cout << "                      " << char(186) << "                                     " << char(186) << endl;
      cout << "                      " << char(186) << "    Thank you for banking with us.   " << char(186) << endl;
      cout << "                      " << char(186) << "                                     " << char(186) << endl;
      cout << "                      " << char(186) << "              Goodbye                " << char(186) << endl;
      cout << "                      " << char(186) << "                                     " << char(186) << endl;
      cout << "                      " << char(200) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(205) << char(188) << endl;
      cout << "                      " << endl;
      pause();

} //End exitScreen Function

************************UTILITY.H *****************************

#include <conio.h> //used for getche()
#include "Constants.h" //used for ClearScreen()
#include <windows.h> //used for toascii()
#include <iostream.h> //used for cout
#include <stdlib.h> //used for atof()
#include <math.h> //used for atof()
#include <string.h> //used for strlen()

static void pause () { //Used to wait for user input

      /*

      Function Name: pause
      Purpose: Used to wait for user input
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: void
      Data Members Accessed: none
      Data Members Modified: none
      Non-local Variables Used: none
      Functions Called: none

      */
      
      //Outputs user message, and waits for user input
      
      cout << "                          " << "Press any key to continue...";
      cout << flush;
      getche();
      ClearScreen;

} //End pause function

static void lower () { //Used to center text

      /*

      Function Name: lower
      Purpose: centers outupt
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: void
      Data Members Accessed: none
      Data Members Modified: none
      Non-local Variables Used: none
      Functions Called: none

      */

      cout << "\n\n\n\n\n" << endl;

} //end lower

static int getPin () { //Used to accept pin
      
      /*

      Function Name: getPin
      Purpose: Used to accept pin
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: int
      Data Members Accessed: none
      Data Members Modified: none
      Non-local Variables Used: none
      Functions Called: none

      */
      
      //Local Variables
      int pinNum = 0; //used to hold pin number
      char pinChar[5]; //used to hold character representation of pin number
      int i = 0; //counter
      char temp; //temporary character holder

      do {

            //Get character from screen            
            cout << flush;
            temp = getch();

            switch (temp) {

                  //Numbers 0-9
                  case toascii(48):
                  case toascii(49):
                  case toascii(50):
                  case toascii(51):
                  case toascii(52):
                  case toascii(53):
                  case toascii(54):
                  case toascii(55):
                  case toascii(56):
                  case toascii(57):
                        //Output "*', and assign temp to pinChar, then increment counter
                        cout << "*";
                        pinChar[i] = temp;
                        ++i;
                        break;
                  //Delete Key
                  case toascii(8):
                        if (i==0) { //If cursor is at starting point, do nothing
                              cout << "";
                        } else { //Clear last input, and decrement counter
                              cout << "\b \b";
                              --i;
                        }
                        break;
                  default:
                        //If invalid characters are inputted, beep
                        MessageBeep(0xFFFFFFFF);
            }

      }while (i < 4); //Loop for only 4 times (number 0 is included)
      
      //Add null character
      pinChar[i] = '\0';

      for (int n = 0; n < 4; n++) {
            
            //Convert (string) pinChar to (integer) pinNum
            pinNum = pinNum*10 + (toascii(pinChar[n]) - 48);

      }

      cout << endl;

      return pinNum;

} //End get pin

static int getNumOnly () { //Gets a numeric input only

      /*

      Function Name: getNunOnly
      Purpose: Used to get a number only
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: int
      Data Members Accessed: none
      Data Members Modified: none
      Non-local Variables Used: none
      Functions Called: none

      */

      //Local Variables
      int acctNum = 0; //Used to hold account number
      char acctChar[5]; //Used to hold character representation of account number
      int i = 0; //Counter
      char temp; //Temporary character holder

      do {

            //Gets charcter from user
            cout << flush;
            temp = getch();

            switch (temp) {

                  //Numbers 0-9
                  case toascii(48):
                  case toascii(49):
                  case toascii(50):
                  case toascii(51):
                  case toascii(52):
                  case toascii(53):
                  case toascii(54):
                  case toascii(55):
                  case toascii(56):
                  case toascii(57):
                        cout << temp; //Output number
                        acctChar[i] = temp; //set acctChar[i] to current temp character
                        ++i;
                        break;
                  //Delete Key
                  case toascii(8):
                        if (i==0) { //If cursor is at starting point, do nothing
                              cout << "";
                        } else {
                              cout << "\b \b"; //Clear last input, and decrement counter
                              --i;
                        }
                        break;
                  default:
                        MessageBeep(0xFFFFFFFF); //If invalid characters are inputted, beep
            }

      }while (i < 4); //Loop for only 4 times (number 0 is included)
      
      //Add null character
      acctChar[i] = '\0';

      for (int n = 0; n < 4; n++) {
            
            //Converts char to int
            acctNum = acctNum*10 + (toascii(acctChar[n]) - 48);

      }

      return acctNum;

} //End getNumOnly();

static double getCurr () { //Gets a currenty amount

      /*

      Function Name: getCurr
      Purpose: Used to accept a currenty value
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: double
      Data Members Accessed: none
      Data Members Modified: none
      Non-local Variables Used: none
      Functions Called: none

      */

      //Local Variables
      double currNum = 0; //Creates a currNum
      char currChar[50]; //Createa a character represenation of currNum
      int i = 0; //Counter
      char temp; //Temporary character
      int dec = 0; //Keeps track of decimal places left
      bool exit = false; //Condition for exiting menu

      do {

            //Gets charcter from user
            currChar[i];
            cout << flush;
            temp = getch();
      
                  switch (temp) {

                        //Numbers from 0-9
                        case toascii(48):
                        case toascii(49):
                        case toascii(50):
                        case toascii(51):
                        case toascii(52):
                        case toascii(53):
                        case toascii(54):
                        case toascii(55):
                        case toascii(56):
                        case toascii(57):
                              cout << temp; //Outputs input
                              currChar[i] = temp; //sets temp character to currChar
                              ++i; //Increments counter
                              --dec;
                              break;
                        //"." key
                        case toascii(46):
                              cout << temp; //Outputs input
                              currChar[i] = temp; //sets temp character to currChar
                              ++i;
                              dec = 2; //Sets decimal to two so user can only input two more numbers
                              break;
                        default:
                              MessageBeep(0xFFFFFFFF); //If invalid characters are inputted, beep
                  }

      }while ((dec != 0) && temp != toascii(13)); //Loops until dec left = 0 (on each run it is negative until the decimal is pressed), or enter is pressed

      int twodec = 0; //Holds a flag for two decimal places
      
      for (unsigned int n = 0; n < strlen(currChar); n++){ //Searches string for multiple "."'s

            if (currChar[n] == '.') {

                  twodec += 1;
      
            }

      }

      if (twodec > 1) { //If there are multiple ".", if so return -1 which will keep user in loop and user will need to input info again

            cout << endl;
            
            return - 1;

      } else { //If there is only 1 decimal or 0 decimals, then return number
      
            currNum = atof(currChar); //converts charcter array to double

            cout << endl;

            return currNum;

      }

} //End getCurr

static void center (char string[]) { //Centers a string

      /*

      Function Name: center
      Purpose: Used to center output
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: void
      Data Members Accessed: none
      Data Members Modified: none
      Non-local Variables Used: none
      Functions Called: none

      */

      //Local Variables
      unsigned int len = strlen(string); //Gets string length
      int space = (80 - len)/2; //Gets needed number of spaces

      //Outputs spaces
      for (int i = 0; i < space; i++) {
            cout << " ";
      }

      //Output string
      cout << string << endl;

} //End center()

static char getYN () { //Gets a y or n value

      /*

      Function Name: getYN
      Purpose: Used to accept y or n value
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: char
      Data Members Accessed: none
      Data Members Modified: none
      Non-local Variables Used: none
      Functions Called: none

      */

      //Local Variables
      char ans; //Holds answer
      bool exit = false; //Condition for exiting loop
      char temp; //Holds temp char

      do { //Loops until valid input is entered

            //Gets input
            cout << flush;
            temp = getch();
      
                  switch (temp) {

                        //Valid input
                        case 'y':
                        case 'n':
                              cout << temp;
                              ans = temp;
                              exit = true;
                              break;
                        //Invalid Input
                        default:
                              MessageBeep(0xFFFFFFFF);
                  }

      }while (!exit);

      cout << endl;

      return ans;

} //End getYN()

static int menuChoice () { //Outputs menu choices

      /*

      Function Name: menuChoce
      Purpose: Used to get a menu choice
      Parameters:
            Input: none
            Input & Output: none
            Output: none
      Return Value: int
      Data Members Accessed: none
      Data Members Modified: none
      Non-local Variables Used: none
      Functions Called: none

      */

      //Local Variables
      int choice; //Holds choice number
      bool exit = false; //Condition for exiting
      char temp; //Temporary character

      do { //Loops until valid input is pressed

            //Gets valid input
            cout << flush;
            temp = getch();
      
                  switch (temp) {

                        //Valid input
                        case toascii(49):
                        case toascii(50):
                        case toascii(51):
                        case toascii(52):
                        case toascii(53):
                        case toascii(54):
                              choice = toascii(temp) - 48; //Sets choice to inputted value
                              exit = true;
                              break;
                        //Invalid input
                        default:
                              MessageBeep(0xFFFFFFFF);
                  }

      }while (!exit);

      cout << endl;

      return choice;

} //End menuChoice()


************************TIME.H *****************************

class Time {
private:
      int year,
            month,
            day,
            dayOfWeek,
            hour24,
            hour12,
            minute,
            second;
      char timeCode[8];
      char ampm[3];
      char mos[10];
      char dOWeek[10];

public:
      // Constructors
      Time();
      Time(int year, int mos, int day, int hour, int min, int sec);
      Time(char * tCode);
      ~Time(); // Destructor
      void reset(); // to reset to current time
      char * getTimeCode();
      int getYear();
      int getMonthAsInt();
      char * getMonthAsString();
      int getDay();
      int getDayOfWeekAsInt();
      char * getDayOfWeekAsString();
      int getHour24();
      int getHour12();
      char * getAMPM();
      int getMinute();
      int getSecond();
      char * getDate();
      char * getTime();
      char * getDateAndTime();
};

************************CONSTATNS.H *****************************

#define ClearScreen system("cls") //Clears console screen
#define PER_STR 50 //Sets common string length to 50
#define CENTER setw(22) //Indents 22 spaces
#define MAX_TRANS_RECORDS 100 //allows only 100 transaction records


If anyone can help with my problem I'd appreciate it.  Thanks.

Ryan

Hi,

Sorry the points are so low.  I only have 70.

Ryan
That has to be some sort of record :)

But I have to nit-pick.  Please paste TIME.CPP
Hi,

Sorry, but there is no TIME.CPP.  All I have is a Time.obj file.  This is a class project.

Ryan
That's interesting.

You see why we are interested in it is because you get a correct value, but then it seems other data/variables/memory might be corrupted as a result of the getTimeCode method.  We cannot tell that though without the code.  All we are seeing is the unusual result of that method causing havoc when it's used before the variable is accessed.

Did you try Axter's NULL trick?  Or the strncpy with 7 and then forcing null termination?
Did you increase the size of time?
If so, what is it's new size?
Try the following:

    Time t;
    char time[9];

    t.reset();// Reset......
    strncpy(time, t.getTimeCode(), 8);
    time[8]=0;

    cout << time;
Hi,

I've tried increasing the size of tempTime to 20, and using the null trick.  Neither work.  At the end of loadRecord I cout all the values.  These values are correct, but in displayRecords, the values are wrong.  If I totally take out time, and just write everything else, it works.

Ryan
Try t.reset()
Axter, I don't think copying past the 7 character's allocated by getTimeCode would be best, at least I believe that's what he said the output always is.

strncpy(time, t.getTimeCode(), 6);
time[7]=0;

should be best.
OK, but I think you mean the following:
strncpy(time, t.getTimeCode(), 6);
time[6]=0;
Hi,

When I debug, in loadRecord this line...

transAmt = newTransAmt;

...gets an access violation.

Ryan
>>...gets an access violation.

Have you tried stepping into the line?

Also, do you have a copy constructor for this type?
No I haven't.  I'm not sure how to.  A copy constructor for what?

Ryan
SOLUTION
Avatar of wayside
wayside

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Release and debug mode did not make a difference.  The time.obj file works fine.

Ryan
Axter, haha, well between us there should be a correct answer somewhere :)

This is getting ridiculous, how big is the Time.obj file?  Just email it to me:  ctaylor@ara.com
The verdict:

Time.obj seems to function correctly.

I do:
  Time t;
  char tmp[8];
  int a = 10;
  a = 20;
  strncpy(tmp, t.getTimeCode(), 7);
  tmp[7] = 0;
  cout << tmp << endl;
  cout << a << endl;

and it comes out just fine.

Use the 8 character array like that, you need 7 characters before the null terminator.
The program still doesn't work.  Try to create a workspace and run it.

Ryan
Any other ideas?

Ryan
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi,

My teacher who supplied the time.obj and time.h files, added anoter function to copy time from a time code.  Basically the same thing as the overloaded constructor, but in a public function form.  Thanks to all that have helped.

Ryan