views:

33

answers:

1

This is an ATM style program, but currently it doesn't do exactly what I need it to do...

I need to get the current balance, and when money is transferred from either checking or savings, it should add it to checking and subtract it from savings. which is does, but not correctly...

Input example

-=[ Funds Transfer ]=-
-=[ Savings to Checking ]=-
Account Name: nomadic
Amount to transfer: $400
New Balance in Checking: $900   // original was 500
New Balance in Savings: $7.7068e+012  // this should now be 1100...

Here is my code, it's a lot of code, but there are no errors, so throwing it into an IDE and compiling should be fairly quick for whoever would like to help.

mainBankClass.h

#ifndef MAINBANKCLASS_H
#define MAINBANKCLASS_H
#include <iostream>
#include <fstream>
#include <string>

using namespace std;


class Banking 
{
protected:
    string  checkAcctName, saveAcctName;        // Name on the account
    int acctNumber[13];         // Account number
    float acctBalance, initSaveDeposit, initCheckDeposit, depAmt;       // amount in account, and amount to deposit

public:
    char getBalanceChoice();        // Get name on account for displaying relevant information
    char newAccountMenu();  // Create a new account and assign it a random account number
    void invalid(char *);       // If an invalid option is chosen
    char menu();                // Print the main menu for the user.
    virtual float deposit(){ return 0; }    // virtual function for deposits
//  virtual float withdrawal() = 0; // Virtual function for withdrawals
    void fatal(char *); // Handles fatal errors.
    Banking();
};


class Checking : public Banking
{
    public:
        friend ostream operator<<(ostream &, Checking &);
        friend istream operator>>(istream &, Checking &);
        Checking operator <= (const Checking &) const;
        void newCheckingAccount();
        void viewCheckingBalance();
        void transferFromSaving();
        float deposit() { return (acctBalance += depAmt); }
};

class Saving : public Banking
{
    public:
        friend ostream &operator<<(ostream &, Saving &);
        friend istream &operator>>(istream &, Saving &);
        Saving operator <= (const Saving &) const;
        void newSavingAccount();
        void viewSavingBalance();
        void transferFromChecking();
        float deposit() { return (acctBalance += depAmt); }
};

class checkAndSave : public Banking
{
    public:
        void newCheckAndSave();
        void viewBothBalances();
};
#endif 

bankAccount.cpp

    #include <iostream>
#include <sstream>
#include <string>
#include <iomanip>
#include <fstream>
#include <time.h>
#include "MainBankClass.h"



/*****************************\
|   BANKING CONSTRUCTOR     |
\*****************************/

Banking::Banking()
{
    string  acctName;       // Name on the account
    acctNumber[13] = 0;         // Account number
    acctBalance = 0;
    initCheckDeposit = 0;
    initSaveDeposit = 0;
    depAmt = 0;     
};

/********************************\
| The following code is to print the menu   |
| and recieve the users choice on what      |
| they want to do with the ATM              |
\********************************/

char Banking::menu()
{
    char choice;

        system("cls");
        cout << "\t\t -=[ Main Menu ]=- \n\n"
               << "\tA) Create New Account\n"
               << "\tB) View Account Balance\n"
               << "\tC) Transfer Funds From Checking To Savings\n"
               << "\tD) Transfer Funds From Savings To Checking\n"
               << "\tE) Exit\n"
               << "\n\n\tSelection: ";
        cin >> choice;
        cin.ignore();
        choice = toupper(choice);

        while(!isalpha(choice))
        {
            invalid("[!!] Invalid selection.\n[!!] Choose a valid option: ");
            cin >> choice;
            cin.ignore();
        }

    return choice;
}

/*********************\
| Will read in account choic  |
| and display it for the user       |
\*********************/

char Banking::getBalanceChoice()
{
    char choice;
    fstream saveFile("saving.dat", ios::in  | ios::beg);
    system("cls");
    cout << "\t\t -=[ View Account Balance ]=-\n\n";

    cout << "A) View Checking Account\n"
          << "B) View Saving Account\n"
          << "C) View Checking \\ Saving Account\n" << endl;
    cout << "Choice: ";
    cin >> choice;
    choice = toupper(choice);

    if(!isalpha(choice))
        fatal(" [!!] Invalid Choice");

    return choice;
}


/***************************\
| Incase an invalid decision to made    |
| this throws the error message sent    |
| to it by the calling area             |
\***************************/
void Banking::invalid(char *msg)
{
    cout << msg;
}


/*************************\
| Used if files can not be opened    |
| and exits with code 251:           |
| miscommunication with server   |
\*************************/

void Banking::fatal(char *msg)
{
    cout << msg;
    exit(1);
}


/***************************\
| Create an account, either checking    |
| or savings, or both.                  |
| Must should create a randomly     |
| generated account number that will    |
| correspond with each account.     |
\***************************/

/************************\

NOTE::  WILL BE UPDATED
TO CONTAIN A PIN FOR
ACCOUNT VERIFICATION

*************************/
char Banking::newAccountMenu()
{
    srand(time(NULL));  // Seed random generator with time initialized to NULL
    char acctChoice;        // choice for the account type


    ofstream checkFile("checking.dat", ios::out  | ios::app);       // For saving checking accounts
    ofstream saveFile("saving.dat", ios::out  | ios::app);          // For saving savings accounts

        system("cls");
        cout << "\t\t-=[ New Account Creation ]=-\n\n" << endl;
        cout << "A) Checking Account\n"
              << "B) Savings Account\n"
              << "C) Checking and Saving Account\n" << endl;
        cout << "New account type: ";
        cin >> acctChoice;
        acctChoice = toupper(acctChoice);
        cin.clear();
        cin.sync();
        return acctChoice;
}





/*********************************************************************
**********************************************************************


                                CHECKING ACCOUNT CODE


**********************************************************************
**********************************************************************/

// New Checking Account Creation
void Checking::newCheckingAccount()
{
    system("cls");
    ofstream checkFile("checking.dat", ios::out  | ios::app);       // For saving checking accounts

    cout << "\t\t -=[ New Checking Account ]=- \n" << endl;
    cout << "Name of the main holder to be on the account: ";
    getline(cin, checkAcctName);
    cout << "Initial deposit amount: $";
    cin >> initCheckDeposit;

    if(initCheckDeposit <= 0)
        {
            while(initCheckDeposit <= 0)
                {
                    invalid("[!!] 0 or negative amount entered\nMaybe a typo?\n");
                    cout << "Deposit Amount: $";
                    cin >> initCheckDeposit;
                }
        }

    if(!checkFile)
        fatal("[!!] Fatal Error 251: Miscommunication with server\n");

    checkFile << checkAcctName << endl;

    for(int j = 0; j < 13; j++)
        {
            acctNumber[j] = (rand() % 10);      // Build a random checking account number
            checkFile << acctNumber[j];
        }

    checkFile << endl;
    checkFile << initCheckDeposit << endl;
    checkFile.close();
}

void Checking::viewCheckingBalance()
{
    fstream checkFile("checking.dat", ios::in  | ios::beg);
    string name;
    int i = 0;
    double balance = 0;

        system("cls");

        cout << "\t\t -=[ View Checking Account ]=-\n\n" << endl;
        cout << "Account Name: ";
        cin.sync();
        getline(cin, name);
        getline(checkFile, checkAcctName);

        while(name != checkAcctName && !checkFile.fail())
        {
            i++;
            getline(checkFile, checkAcctName);
        }

        if(name == checkAcctName)
          {
                system("cls");
                cout << "\t\t -=[ Checking Account Balance ]=-\n\n" << endl;
                cout << "Account Name: " << checkAcctName << "\n";
                cout << "Account Number: ";
                for(int j = 0; j < 13; j++)
                {
                    char input_number; 
                    stringstream converter;
                    checkFile.get(input_number);
                    converter << input_number;
                    converter >> acctNumber[j];
                    cout << acctNumber[j];
                }
                // if balance a problem, try the below commented out line
                // checkFile.ignore(numeric_limits<streamsize>::max(), '\n');                
                cout << endl;
                checkFile >> acctBalance;
                cout << "Balance: $" << fixed << showpoint << setprecision(2) << acctBalance << endl;
           }
        else
            fatal("[!!] Invalid Account\n");
        checkFile.close();
        getchar();
}

void Checking::transferFromSaving() // Move funds FROM SAVINGS to CHECKING
{
    system("cls");
    string name;
    long checkPos = 0;
    long savePos = 0;
    float savingBalance = 0;
    string saveAcctName;
    int i = 0;
    cin.clear();
    fstream saveFile("saving.dat", ios::in | ios::out  | ios::beg);
    fstream checkFile("checking.dat", ios::in | ios::out  | ios::beg);

    cout << "\t\t-=[ Funds Transfer ]=-" << endl;
    cout << "\t\t-=[ Savings to Checking ]=-" << endl;

    cout << "Account Name: ";
    cin.sync();
    getline(cin, name);
    getline(checkFile, checkAcctName);

    while(name != checkAcctName && !checkFile.fail())
    {
        i++;
        getline(checkFile, checkAcctName);
    }

    getline(saveFile, saveAcctName);
    while(name != saveAcctName && !saveFile.fail())
    {
        i = 0;
        i++;
        getline(saveFile, saveAcctName);
    }


    if(name == checkAcctName)
     {
         cout << "Amount to transfer: $";
         float depAmt = 0;
         cin >> depAmt;

         for(int j = 0; j < 13; j++)
        {
             char input_number; 
            stringstream converter;
            checkFile.get(input_number);
            converter << input_number;
            converter >> acctNumber[j];
        }

         checkPos = checkFile.tellg();      // if the file is found, get the position of acctBalance and store it in ptrPos
        checkFile.seekg(checkPos);
         checkFile >> acctBalance;
         savePos = saveFile.tellg();
         saveFile.seekg(savePos);   // sending the cursor in the file to ptrPos + 1 to ignore white space
         saveFile >> savingBalance;

         if(savingBalance < depAmt) // if checking account does not have enough funds, exit with NSF code
             fatal("[!!] Insufficient Funds\n");

         acctBalance += depAmt;     // can be changed to an overloaded operator
         savingBalance -= depAmt;   // can be changed to an overloaded operator
         checkFile.seekp(checkPos); // go to position previously set above
         checkFile << acctBalance;      // write new balance to checkFile
         saveFile.seekp(savePos);   // same thing as above comment
         saveFile << savingBalance; // write new balance to saveFile
         cout << "New Balance in Checking: $" << acctBalance << endl;   // will be removed later
         cout << "New Balance in Savings: $" << savingBalance << endl;  // will be removed later aswell
    }
    else 
        fatal("[!!] Linked accounts do not exist.\n");      // if account is not found

    saveFile.close();
    checkFile.close();
}




/********************************************************
********************************************************

                        SAVING ACCOUNT CODE

*********************************************************
*********************************************************/


void Saving::newSavingAccount()
{
    system("cls");
    ofstream saveFile("saving.dat", ios::out  | ios::app);          // For saving savings accounts
    cout << "\t\t -=[ New Savings Account ]=- \n" << endl;

    cout << "Name of the main holder to be on account: ";
    getline(cin, saveAcctName);
    cout << "Deposit Amount: $";
    cin >> initSaveDeposit;

    if(initSaveDeposit <= 0)
    {
        while(initSaveDeposit <= 0)
            {
                invalid("[!!]0 or negative value entered.\nPerhaps a typo?\n");
                cout << "Deposit amount: $";
                cin >> initSaveDeposit;
            }
    }

    if(!saveFile)
        fatal("[!!] Fatal Error 251:  Miscommunication with server\n");

    saveFile << saveAcctName << endl;
    for(int j = 0; j < 13; j++)
        {
            acctNumber[j] = (rand() % 10);
            saveFile << acctNumber[j];
        }
    saveFile << endl;
    saveFile << initSaveDeposit << endl;
    saveFile.close();
}

void Saving::viewSavingBalance()
{
    string name;
    int i = 0;
    fstream saveFile("saving.dat", ios::in  | ios::beg);
    cin.clear();
    system("cls");
    cout << "\t\t -=[ View Saving Account ]=-\n\n" << endl;
    cout << "Account Name: ";
    cin.sync();
    getline(cin, name);
    getline(saveFile, saveAcctName);

    while(name != saveAcctName && !saveFile.fail())
    {
        i++;
        getline(saveFile, saveAcctName);
    }

    if(name == saveAcctName)
     {
         system("cls");

        cout << "\t\t -=[ Saving Account Balance ]=-\n\n" << endl;
        cout << "Account Name: " << saveAcctName << "\n";
        cout << "Account Number: ";

        for(int j = 0; j < 13; j++)
        {
             char input_number; 
            stringstream converter;
            saveFile.get(input_number);
            converter << input_number;
            converter >> acctNumber[j];
            cout << acctNumber[j];
        }
        // if balance a problem, try the below commented out line
         // checkFile.ignore(numeric_limits<streamsize>::max(), '\n');                
     cout << endl;
     saveFile >> acctBalance;
     cout << "Balance: $" << fixed << showpoint << setprecision(2) << acctBalance << endl;
    }
    else
        fatal("[!!] Invalid Account\n");
    saveFile.close();
    getchar();
}


// NEED TO WORK ON THIS PORTION TOMORROW AND MONDAY, ADD OVERLOADED OPS FOR ASSIGNMENT!!!!!!!
void Saving::transferFromChecking() // This is to take money FROM checking and ADD IT TO SAVING
{
    system("cls");
    string name;
    long savePos = 0;
    long checkPos = 0;
    float checkingBalance = 0;
    string checkAcctName;
    int i = 0;
    cin.clear();
    fstream saveFile("saving.dat", ios::in | ios::out  | ios::beg);
    fstream checkFile("checking.dat", ios::in | ios::out  | ios::beg);

    cout << "\t\t-=[ Funds Transfer ]=-" << endl;
    cout << "\t\t-=[ Checking to Savings ]=-" << endl;

    cout << "Account Name: ";
    cin.sync();
    getline(cin, name);
    getline(saveFile, saveAcctName);
    getline(checkFile, checkAcctName);

    while(name != saveAcctName && name != checkAcctName && !saveFile.fail() && !checkFile.fail())
    {
        i++;
        getline(saveFile, saveAcctName);
        getline(checkFile, checkAcctName);
    }

    if(name == saveAcctName)
     {
         cout << "Amount to transfer: $";
         float depAmt = 0;
         cin >> depAmt;

         for(int j = 0; j < 13; j++)
        {
             char input_number; 
            stringstream converter;
            saveFile.get(input_number);
            converter << input_number;
            converter >> acctNumber[j];
        }

        savePos = saveFile.tellg();     // if the file is found, get the position of acctBalance and store it in ptrPos
        saveFile.seekg(savePos);
        saveFile >> acctBalance;
        checkPos = checkFile.tellg();
        checkFile.seekg(checkPos);              // if file is found, store current position of the cursor to ptrPos
        checkFile >> checkingBalance;

         if(checkingBalance < depAmt)   // if checking account does not have enough funds, exit with NSF code
             fatal("[!!] Insufficient Funds\n");    // Can also place overloaded op here

         acctBalance += depAmt;     // can be changed to an overloaded operator
         checkingBalance -= depAmt; // can be changed to an overloaded operator
         saveFile.seekg(savePos);   // go to position previously set above
         saveFile << acctBalance;       // write new balance to saveFile
         checkFile.seekg(checkPos); // same thing as above comment
         checkFile << checkingBalance;  // write new balance to checkFile
         cout << "New Balance in Savings: $" << acctBalance << endl;    // will be removed later
         cout << "New Balance in Checking: $" << checkingBalance << endl;   // will be removed later aswell
    }
    else 
        fatal("[!!] Linked accounts do not exist.\n");      // if account is not found

    saveFile.close();
    checkFile.close();
}

/********************************************
********************************************

            CHECK AND SAVE CODE

**********************************************
**********************************************/

void checkAndSave::newCheckAndSave()
{
    system("cls");
    ofstream saveFile("saving.dat", ios::out  | ios::app);          // For saving savings accounts
    ofstream checkFile("checking.dat", ios::out  | ios::app);       // For saving checking accounts

    cout << "\t -=[ New Checking & Saving Account ]=- \n" << endl;

    cout << "Name of the main holder to be on account: ";
    getline(cin, checkAcctName);
    saveAcctName = checkAcctName;
    cout << "Checking Deposit Amount: $";
    cin >> initCheckDeposit;

    if(initCheckDeposit <= 0)
    {
        while(initCheckDeposit <= 0)
        {
            invalid("[!!] 0 or negative amount entered\nMaybe a typo?\n");
            cout << "Deposit Amount: $";
            cin >> initCheckDeposit;
        }
    }

    cout << "Saving Deposit Amount: $";
    cin >> initSaveDeposit;

    if(initSaveDeposit <= 0)
    {
        while(initSaveDeposit <= 0)
        {
            invalid("[!!]0 or negative value entered.\nPerhaps a typo?\n");
            cout << "Deposit amount: $";
            cin >> initSaveDeposit;
        }
    }


    if(!saveFile || !checkFile)
        fatal("[!!] Fatal Error 251:  Miscommunication with server\n");

    checkFile << checkAcctName << endl;
    saveFile << saveAcctName << endl;

    for(int j = 0; j < 13; j++)
    {
        acctNumber[j] = (rand() % 10);
        checkFile << acctNumber[j];
        saveFile << acctNumber[j];
    }

    saveFile << endl;
    saveFile << initSaveDeposit << endl;

    checkFile << endl;
    checkFile << initCheckDeposit << endl;
    checkFile.close();
    saveFile.close();
}

void checkAndSave::viewBothBalances()
{
    string name;
    int i = 0;
    fstream checkFile("checking.dat", ios::in  | ios::beg);
    fstream saveFile("saving.dat", ios::in  | ios::beg);
    system("cls");
            cin.clear();
            cout << "\t-=[ Saving & Checking Account Balance ]=-\n\n" << endl;
            cout << "Account Name: ";
            cin.sync();
            getline(cin, name);
            getline(checkFile, checkAcctName);
            saveAcctName = name;

            /**********************\
            | Checking Account portion  |
            | of the checking & savings |
            | overview                      |
            \**********************/
        while(name != checkAcctName && !checkFile.fail())
        {
            i++;
            getline(checkFile, checkAcctName);
        }

        system("cls");
        if(name != checkAcctName && checkFile.fail())
            invalid("\n\n[!!] No Checking Account Found\n");

        cout << "\t\t -=[ Checking Account ]=- \n" << endl;
        cout << "Account Name: " << checkAcctName << "\n";
          cout << "Account Number: ";

        for(int j = 0; j < 13; j++)
          {
              char input_number; 
              stringstream converter;
              checkFile.get(input_number);
               converter << input_number;
               converter >> acctNumber[j];
               cout << acctNumber[j];
           }
                // if balance a problem, try the below commented out line
                // checkFile.ignore(numeric_limits<streamsize>::max(), '\n');                
                cout << endl;
                checkFile >> acctBalance;
                cout << "Balance: $" << fixed << showpoint << setprecision(2) << acctBalance << endl;

             /*********************\
             | Saving Account portion       |
             | of the checking & saving     |
             | overview                     |
             \*********************/
             getline(saveFile, saveAcctName);
            while(name != saveAcctName && !saveFile.fail())
            {
                i++;
                getline(saveFile, saveAcctName);
            }

            if(name != saveAcctName && saveFile.fail())
                invalid("\n\n[!!] No Saving Account Found\n");

            if(name == saveAcctName)
             {
                   cout << "\t\t -=[ Saving Account ]=-\n\n" << endl;
                   cout << "Account Name: " << saveAcctName << "\n";
                   cout << "Account Number: ";

                 for(int j = 0; j < 13; j++)
                   {
                       char input_number; 
                      stringstream converter;
                      saveFile.get(input_number);
                      converter << input_number;
                      converter >> acctNumber[j];
                      cout << acctNumber[j];
                  }
                  // if balance a problem, try the below commented out line
                  // checkFile.ignore(numeric_limits<streamsize>::max(), '\n');                
                  cout << endl;
                  saveFile >> acctBalance;
                  cout << "Balance: $" << fixed << showpoint << setprecision(2) << acctBalance << endl;
             }

        if(name != saveAcctName && name != checkAcctName && saveFile.fail() && checkFile.fail())
             fatal("[!!] No Accounts Have Been Found\n");

         checkFile.close();
         saveFile.close();
         getchar();
}

Main.cpp

#include <iostream>
#include "MainBankClass.h"
using namespace std;



int main()
{
    Banking bank;
    Checking check;
    Saving save;
    checkAndSave CanS;
    char choice;

    choice = bank.menu();       // Call the banking menu
    switch(choice)
        {
            case 'A':
                choice = bank.newAccountMenu();
                    switch(choice)
                        {
                            case 'A':
                                check.newCheckingAccount();
                                break;

                            case 'B':
                                save.newSavingAccount();
                                break;

                            case 'C':
                                CanS.newCheckAndSave();
                                break;

                            default:
                                system("cls");
                                bank.fatal("[!!] Invalid option\n");
                                break;
                        }
                break;
/***********************************************/
            case 'B':
                choice = bank.getBalanceChoice();
                    switch(choice)
                    {
                        case 'A':
                            check.viewCheckingBalance();
                            break;
                        case 'B':
                            save.viewSavingBalance();
                            break;
                        case 'C':
                            CanS.viewBothBalances();
                            break;
                        default:
                            bank.fatal("Invalid decision\n");
                            break;
                    }
/*************************************************/             
                break;
            case 'C':
                check.transferFromSaving();
                break;
            case 'D':
                save.transferFromChecking();
                break;
            case 'E':
                system("cls");
                cout << "\t\t-=[ Disconnecting From System ]=-\n";
                cout << "\t\t\t  Thank you" << endl;
                cout << "\t\t       Have a nice day!" << endl;
                exit(1);
                break;
            default:
                system("cls");
                bank.invalid("\n\n\n\n\t\t [+] Invalid Selection \n\t\t[+] Disconnecting From System \n\t\t\tGood-bye \n\n\n\n\n\n\n");
                exit(1);
                break;
        }

    return 0;
}
+1  A: 

This kind of error is just crying out for a debugger. I don't know what your problem is here (the code is long), but I know if you just step through this in a debugger you'll be able to see exactly the moment when things go bad.

dicroce
I tried stepping through it with a debugger and it shows correct values until it hits the file writing portion where it kicks me off to the fstream library file
IngeniousHax