Thread: Trouble reading from txt file

  1. #1
    Registered User
    Join Date
    Sep 2010
    Posts
    1

    Trouble reading from txt file

    Having trouble with a function in an assignment. The function should read transaction data from a txt file until the end of the file is reached. A typical transaction is shown below. The first field on the transaction record is the date of the transaction, followed by an account number, then the transaction type ('C' for charge or 'P' for payment), and finally a transaction amount.

    06/19 1111-1111-1111-1111 C 430.00

    Once all of the data for a given transaction has been read, search the accounts array for the account number given in the transaction. If the account number is present in the array, then the transaction may be processed. For a payment, simply call the process_payment() method for the object that contains a matching account number, passing it the transaction amount. For a charge, call the process_charge() method for the object that contains a matching account number, passing it the transaction amount.

    For each transaction record, print a line in a transaction report with the data from the record and the updated balance for that account. If the balance is negative, it should be printed as a positive number but followed by the letters "CR". If the transaction account number was not found in the account array or if a charge exceeded the account's credit limit (i.e., if the process_charge() method returned false), print an appropriate error message instead of the account balance.

    After all transactions have been processed, close the transaction file.

    I have the rest of the program written, I'm just stuck on (what I believe to be) the logic of this part and how to read from the file and then compare it to the Class array I built earlier. My code is below and the function I'm having issues with is process_transactions (at the very bottom) Thanks in advance:


    Code:
    /*******************************************************************************
       PROGRAM:   Program 2 - Classes
       AUTHOR:    Brandon Rogers
    
       FUNCTION:  This program will implement a small database of
                  credit card accounts.  A file of charge and payment
                  transactions will be applied to the accounts.
    
       INPUT:     1) accounts   A binary file used to build the array
                                of CreditAccounts.
                                /home/turing/abyrnes/input/cs241/fall10/accounts
                                
                  2) trans      A regular text file that contains the
                                different transactions that will be applied
                                to the array of CreditAccounts.
                                /home/turing/abyrnes/input/cs241/fall10/trans              
    
       OUTPUT:    Reports containing an initial Credit Account Listing, a 
                  Transaction Report and an updated Credit Account Listing.
                  
    
    *******************************************************************************/
    
    #include <iostream>
    #include <iomanip>
    #include <fstream>
    
    #define SIZE 20
    #define ACCOUNTS /home/turing/abyrnes/input/cs241/fall10/accounts
    #define TRANS /home/turing/abyrnes/input/cs241/fall10/trans
    
    using namespace std;
    
    class CreditAccount
    {      
           public:
                 CreditAccount();  // Constructor
                 char* get_accountNumber();
                 float get_balance();
                 void process_payment( float );
                 bool process_charge( float );
                 void print();
                 
           private:
                  char acctNum[20];
                  char custName[21];
                  int expMonth;
                  int expYear;
                  float creditLimit;
                  float currentBal;
    };
    
    /****************************************************************
    
       FUNCTION:   CreditAccount - constructor
    
       ARGUMENTS:  none
    
       RETURNS:    nothing
    
       NOTES:      Initializes the string data members of the class 
                   to null and all of the numeric data members to 0
                   
    ****************************************************************/
    CreditAccount::CreditAccount()
    {
    acctNum[0] = '\0';
    custName[0] = '\0';
    expMonth = 0;
    expYear = 0;
    creditLimit = 0;
    currentBal = 0;
    }
    
    /****************************************************************
    
       FUNCTION:   get_accountNumber
    
       ARGUMENTS:  none
    
       RETURNS:    a pointer to the first character of the account number
       
    ****************************************************************/
    char* CreditAccount::get_accountNumber()
    {
    return & acctNum[0];
    }                   
    
    /****************************************************************
    
       FUNCTION:   get_balance
    
       ARGUMENTS:  none
    
       RETURNS:    the balance
       
    ****************************************************************/
    float CreditAccount::get_balance()
    {
    return currentBal;
    }
                    
    /****************************************************************
    
       FUNCTION:   process_payment
    
       ARGUMENTS:  a float payment amount
    
       RETURNS:    nothing
    
       NOTES:      subtracts the payment amount from the balance
       
    ****************************************************************/     
    void CreditAccount::process_payment(float paymentAmt)
    {
    currentBal -= paymentAmt;                                    
    }
    
    /****************************************************************
    
       FUNCTION:   process_charge
    
       ARGUMENTS:  a float charge amount
    
       RETURNS:    a boolean value
    
       NOTES:      If the charge amount plus the current balance is 
                   greater than the credit limit, the method returns
                   false without changing the balance.  Otherwise, the
                   charge amount is added to the balance and the
                   method returns true.
       
    ****************************************************************/  
    bool CreditAccount::process_charge( float chargeAmt )
    {
    if( chargeAmt + currentBal > creditLimit )
        return false;
    else
        currentBal += chargeAmt;
        return true;                               
    }
    
    /****************************************************************
    
       FUNCTION:   print
    
       ARGUMENTS:  none
    
       RETURNS:    nothing
    
       NOTES:      prints the data members of the object on one line.
                   if the balance is negative, it will print as a
                   positive number followed by "CR" (for credit).
       
    ****************************************************************/  
    void CreditAccount::print()
    {
    cout << left << showpoint << fixed << setprecision(2)
         << setw(22) << acctNum << setw(20) << custName;
         
         if( expMonth < 10 )
         {
         cout << "0" << expMonth;
         }
         
         else
         {
         cout << expMonth;
         }
         
    cout << "/"<< setw(7) << expYear;
    cout << right << setw(10) << creditLimit 
         << setw(14) << currentBal << endl;
    }
    
    
    // Function Prototypes:
    int read_accounts( CreditAccount[] );
    void print_accounts( CreditAccount[], int );
    void process_transactions( CreditAccount[], int );
    
    int main()
    {
    CreditAccount creditArr[SIZE];    
    int validAccts = 0;
    
    validAccts = read_accounts( creditArr ); 
    
    print_accounts( creditArr, validAccts );
    
    process_transactions( creditArr, validAccts );
    
    print_accounts( creditArr, validAccts );
    
    cout << endl;
    system( "pause" );
    return 0;    
    }
    
    /****************************************************************
    
       FUNCTION:   read_accounts
    
       ARGUMENTS:  An array of CreditAccount objects.
    
       RETURNS:    The number of accounts read into the array.
    
       NOTES:      This function reads data for the credit card accounts
                   from a file into the account array.
    ****************************************************************/
    int read_accounts( CreditAccount Arr[] )
    {
    CreditAccount temp;
    ifstream inFile;  
    int i = 0; // # of accounts read
        
    inFile.open( "ACCOUNTS", ios::binary );
    if( inFile.fail() )
      {
      cout << "file failed to open";
      exit( -1 );
      }
    
    inFile.read( (char * ) &temp, sizeof( temp ) );
    
    while( inFile )
    {
           Arr[i] = temp;
           
           i++;
           
           inFile.read( (char * ) &temp, sizeof( temp ) );
    }
    
    inFile.close();
    
    return i;
      
    }
    
    /****************************************************************
    
       FUNCTION:   print_accounts
    
       ARGUMENTS:  1)  Array of CreditAccount objects
                   2)  Number of valid accounts stored in the array (int)
    
       RETURNS:    nothing
    
       NOTES:      This function prints a report header and column headers
                   and then loops through the valid accounts in the
                   account array and calls each object's print() method
       
    ****************************************************************/
    void print_accounts( CreditAccount Arr[], int validAccts )
    {
    int i;     
    
    cout << endl << " " << setw(48) << "Credit Account Listing" << endl << endl
         << setw(61) << "Credit" << setw(15) << "Account" << endl
         << "Account Number" << setw(12) << "Name" << setw(24) 
         << "Exp. Date" << setw(10) << "Limit" << setw(16) 
         << "Balance" << endl
         << "----------------------------------------------------------------------------"
         << endl << endl;
    
    for( i = 0; i < validAccts; i++ )
    {
    Arr[i].print();
    }
    
    }
    
    /****************************************************************
    
       FUNCTION:   process_transactions
    
       ARGUMENTS:  1)  Array of CreditAccount objects
                   2)  Number of valid accounts stored in the array (int)
    
       RETURNS:    nothing
    
       NOTES:      This function opens the file trans for input.  Before
                   reading any transactions, the function prints a report
                   header and column headers.  It then reads transaction
                   data from the file until the end of the file is reached.
                   
       
    ****************************************************************/
    void process_transactions( CreditAccount Arr[], int validAccts )
    {
    char temp;
    char transAr[100];
    ifstream inFile;
    int i = 0;
    
    inFile.open( "TRANS" );
    if( inFile.fail() )
      {
      cout << "file failed to open";
      exit( -1 );
      }
      
    cout << endl << " " << setw(48) << "Transaction Report" << endl << endl
         << "Date" << setw(10) << "Account" << setw(10) << "Type" << setw(10)
         << "Amount" << setw(15) << "New Balance" << endl << endl;
    
    inFile.read( (char * ) &temp, sizeof( temp ) );
    
    while( inFile )
    {
           transAr[i] = temp;
    
           i++;
           
           inFile.read( (char * ) &temp, sizeof( temp ) );
    
    }
    inFile.close();
    }

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    It seems you have #define'd some file paths, which is fine, but they would be something like

    #define TRANS "path/to/file.txt"

    and not like what you have. And the reason the file name is in quotes and not the identifier TRANS is because the path is the string you want to pass in, but not the string "TRANS" or "ACCOUNTS". I'm not sure, but also note that C++ cannot open directories (as in, trans is not a file but a folder) which may also be an issue.

    I think you're not reading the transaction file right, either. What you have now basically reads one character at a time, when C++ ifstreams can read a lot smarter than that.

    Try one line at a time:
    Code:
    string date;
    string accountid;
    char transType;
    double amount;
    
    file >> date >> accountid >> transType >> amount;
    if (file)
    {
       // successful read
       print_transaction();
    }
    else 
    {
       file.close();
       cout << "Your file has format errors in it\n";
       // quit
    }
    Haven't compiled but it should be something to this effect.


    You don't really say where your file handling is broken so that is all I can say.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. problem reading numbers in a txt file
    By nimamc in forum C Programming
    Replies: 3
    Last Post: 06-03-2009, 02:35 PM
  2. Reading a txt file into an array: unexpected segfault
    By pistacchio in forum C Programming
    Replies: 3
    Last Post: 05-05-2009, 04:27 PM
  3. help with text input
    By Alphawaves in forum C Programming
    Replies: 8
    Last Post: 04-08-2007, 04:54 PM
  4. trouble reading a file
    By cky799 in forum C Programming
    Replies: 10
    Last Post: 04-21-2004, 07:20 PM
  5. what does this mean to you?
    By pkananen in forum C++ Programming
    Replies: 8
    Last Post: 02-04-2002, 03:58 PM