0

Trying to create an algorithm that an ATM would use, but after selecting a choice to enter card number or exit, the code keeps looping back to this question. Still new to C++ and this has me stumped. I believe that my issue is at the beginning of the code because I can't get far into the program before it starts to loop.

#include <iostream>
#include <string>
#include <vector>
using namespace std;
// abstract class
struct Person
{
    string name;
    virtual void printName() = 0;
};
//Account class
struct Account : public Person
{
    long cardNumber;
    int pin; // 4 digit pin
    double balance;

    Account()
    {
        cardNumber = 0;
        pin = 1234;
        balance = 0;
    }

    Account(long c, int p, double bal)
    {
        cardNumber = c;
        pin = p;
        balance = bal;
    }

    void withdraw()
    {
        double amount;
        cout << "Enter amount less than " << balance << ": ";
        cin >> amount;
        balance -= amount;
        checkBalance();
    }

    void checkBalance()
    {
        cout << "Your balance is: " << balance << endl;
    }

    void changePin()
    {
        int Pin;
        cout << "ENTER NEW PIN: ";
        cin >> Pin;
        pin = Pin;
        cout << "PIN CHANGED \n";
    }

    void printName()
    {
        cout << "Name of Person: ";
        cout << name << endl;
    }
};

struct ATM
{
    vector<Account> accounts;

    void Login()
    {
        long cardNumber;
        cout << "Enter cardNumer: ";
        cin >> cardNumber;
        for (int i = 0; i < accounts.size(); ++i)
        {
            if (cardNumber == accounts[i].cardNumber)
            {
                long pin;
                cout << "Enter PIN: ";
                cin >> pin;
                if (pin == accounts[i].pin)
                {
                    int choice = 0;
                    cout << "1. WITHDRAW\n";
                    cout << "2. CHECK BALANCE\n";
                    cout << "3. CHANGE PIN\n";
                    cout << "4. EXIT\n";
                    cout << "Enter your choice: ";
                    cin >> choice;
                    switch (choice)
                    {
                    case 1: accounts[i].withdraw();
                        break;
                    case 2: accounts[i].checkBalance();
                        break;
                    case 3: accounts[i].changePin();
                        break;
                    case 4: cout << "THANK YOU FOR USING\n";
                        break;
                    default: cout << "NO A VALID CHOICE BYE!!\n";
                    }
                }
                else
                    cout << "WRONG PIN BYE!!";
            }
        }
    }
};

int main()
{
    int choice = 0;
    ATM A;
    Account temp;
    temp.name = "John Doe";
    temp.cardNumber = 123456789;
    temp.pin = 1234;
    temp.balance = 30000;
    A.accounts.push_back(temp);
    temp.name = "David Joe";
    temp.cardNumber = 987654321;
    temp.pin = 4321;
    temp.balance = 10000;
    A.accounts.push_back(temp);
    while (choice != 2)
    {
        cout << "1. LOGIN\n";
        cout << "2. EXIT\n";
        cout << "ENTER CHOICE: ";
        cin >> choice;
        switch (choice)
        {
        case 1: A.Login();
            break;
        case 2: cout << "BYE!!\n";
            break;
        default: cout << "ENTER A VALID CHOICE\n";
        }
    }
}

Any help is much appreciated.

Swordfish
  • 12,971
  • 3
  • 21
  • 43
  • Welcome to Stack Overflow! Could you format your code nicely? Indent things correctly and remove all those unnecessary blank lines? Poorly formatted code is hard to read, and hard to read => hard to help. – Pranav Hosangadi Sep 04 '20 at 00:28
  • And when you used your debugger to run your program, what did you see? This is precisely what a debugger is for. If you don't know how to use a debugger this is a good opportunity to learn how to use it to run your program one line at a time, monitor all variables and their values as they change, and analyse your program's logical execution flow. Knowing how to use a debugger is a required skill for every C++ developer, no exceptions. With your debugger's help you should be able to quickly find all bugs in this and all future programs you write, without having to ask anyone for help. – Sam Varshavchik Sep 04 '20 at 00:34
  • *`double balance;`* – serious?? – Swordfish Sep 04 '20 at 00:40
  • @Swordfish, this is obviously an educational assignment so `double` is the natural type for a floating point balance, despite the fact it may be problematic in the real world due to precision limitations. Unless your bank balance is *much* bigger than mine, double precision should be able to handle this scenario where you're only subtracting things :-) In other words, not *that* much error will be introduced, probably not enough for the minimal amount of test data likely to be used in an educational setting. – paxdiablo Sep 04 '20 at 00:47
  • @paxdiablo Sure, you're right. Let's teach fundamental errors in exercises. – Swordfish Sep 04 '20 at 00:48
  • hey matt I tried debugging your code in code blocks and everything seem to work fine! what is the problem exactly ? you can tell me and I'll help you or you can stick a few "cout"s in some places of your code and check for your self ok ? – Ronald joe Sep 04 '20 at 00:51
  • @Swordfish: I'm going to *assume* that's sarcasm, it's sometimes hard to tell on the net. If it is, you may *also* want to raise the issue of not checking whether the `operator<<` calls fail, the fact that no checking for overdrawing is done other than the suggestion you don't do it, and various other things. There are many issues in this code that would make it unsuitable in the real world, but few of them would be useful to bring up at this level, unless you want to annoy your educator by bringing in GMP or MPIR, or making the code so rock solid it's ten time longer :-) – paxdiablo Sep 04 '20 at 00:52
  • make sure that the input you're using for choice is 1 or 2 not "1" or "2" – Ronald joe Sep 04 '20 at 00:55
  • 1
    The kicker is, if you're going to express disbelief about a coding choice to a rookie coder, you should explain why you are disbelieving. Even if it's inconvenient in the now, at least they'll learn something for later. – user4581301 Sep 04 '20 at 00:55
  • @user4581301 so i should rewrite that code?? – Swordfish Sep 04 '20 at 00:56
  • 1
    @Swordfish: rewrite *what* code exactly? The OP's? I would suggest not. Your formatting changes were good but fundamentally changing the code would probably be much more prone to invalidating the question. I think it's enough that you've *mentioned* the problems. And, just to be clear, the *reason* behind not using something like `double` in the real world is that errors *can* be introduced under certain circumstances. You would be better off using an arbitrary-precision library so as to avoid this (but not for simple classwork assignments, which is the point I was trying to get across). – paxdiablo Sep 04 '20 at 00:59
  • 1
    Dear OP. `double` or any other floating point representation isn't suitable for amounts of money. You (better: your clients) will find to have lost or gained money out of nowhere because of the limited precision of floating point math. See: [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) Use integers (no, integers doesn't mean `int` ...) and a different unit. 1/100 of base unit or 1/1000. – Swordfish Sep 04 '20 at 01:03
  • I consider this (avoiding doubles) is bad advice, not because it's wrong but because it's mistargeted. Every data type has its limitations and, as long as you understand/mitigate them, it will be fine. For example, integers also have a much more limited range than doubles although *within* that range, precision is perfect. Even GMP/MPIR has limits. You have to understand the environment and *this* environment is a simple educational one where doubles should be okay. – paxdiablo Sep 04 '20 at 06:08

1 Answers1

1

Other than a misspelt cardNumer, and a signed/unsigned comparison warning which can be fixed with:

for (size_t i = 0; i < accounts.size(); ++i)

there's nothing really wrong with that code, as evidenced by the following run:

1. LOGIN
2. EXIT
ENTER CHOICE: 1
Enter cardNumer: 7
1. LOGIN
2. EXIT
ENTER CHOICE: 1
Enter cardNumer: 123456789
Enter PIN: 1234
1. WITHDRAW
2. CHECK BALANCE
3. CHANGE PIN
4. EXIT
Enter your choice: 2
Your balance is: 30000
1. LOGIN
2. EXIT
ENTER CHOICE:

If you enter an invalid card number, it will go back to the main menu but the question is not really clear on that behaviour, and you haven't specified what test data you're using.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953