Saturday, April 4, 2026

ATM Simulator || 16 Intermediate Level C++ Projects

Summary: 

A robust, console-based simulation of an Automated Teller Machine. This project demonstrates the core pillars of Object-Oriented Programming (Encapsulation, Abstraction, and Data Integrity) by managing secure user sessions, balance persistence, and transaction validation.

Learning Objectives:

  • Encapsulation: Protecting sensitive data (PIN, Balance) using private access modifiers.

  • Input Validation: Implementing robust error handling for non-numeric inputs using <limits>.

  • Formatted Output: Using <iomanip> to ensure monetary values are displayed with two decimal places.

  • State Management: Handling the logic flow between authentication, transaction, and exit states.

The Source Code

This code is optimized for the MinGW compiler. It includes pre-emptive clearing of the input buffer to prevent common "looping" bugs in the Code::Blocks console environment.

#include <iostream>
#include <string>
#include <iomanip>
#include <limits>

using namespace std;

// Class representing the Bank Account / ATM Logic
class ATM {
private:
    string accountHolder;
    int pin;
    double balance;

public:
    // Constructor
    ATM(string name, int p, double initialCap)
        : accountHolder(name), pin(p), balance(initialCap) {}

    // Validation
    bool authenticate(int enteredPin) {
        return enteredPin == pin;
    }

    // Transactions
    void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            cout << "\n[Success] Deposit of $" << fixed << setprecision(2) << amount << " processed.";
        }
    }

    bool withdraw(double amount) {
        if (amount > balance) {
            cout << "\n[Error] Insufficient funds. Available: $" << fixed << setprecision(2) << balance;
            return false;
        } else if (amount <= 0) {
            cout << "\n[Error] Invalid amount.";
            return false;
        }
        balance -= amount;
        cout << "\n[Success] Please collect your $" << fixed << setprecision(2) << amount;
        return true;
    }

    double getBalance() const {
        return balance;
    }

    string getName() const {
        return accountHolder;
    }
};

// Helper function to handle non-numeric input errors in MinGW/Code::Blocks
void clearBuffer() {
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
}

int main() {
    ATM myAccount("Academic User", 1234, 1000.00);
    int enteredPin, choice;
    double amount;
    bool isAuthenticated = false;

    cout << "--- WELCOME TO THE C++ ACADEMIC BANK ---" << endl;
   
    // Login Loop
    while (!isAuthenticated) {
        cout << "Enter 4-Digit PIN: ";
        if (!(cin >> enteredPin)) {
            cout << "Invalid input type. Please enter numbers only." << endl;
            clearBuffer();
            continue;
        }
       
        if (myAccount.authenticate(enteredPin)) {
            isAuthenticated = true;
            cout << "\nAccess Granted. Welcome, " << myAccount.getName() << "!" << endl;
        } else {
            cout << "Incorrect PIN. Try again." << endl;
        }
    }

    // Menu Loop
    do {
        cout << "\n\n--- MAIN MENU ---" << endl;
        cout << "1. Check Balance" << endl;
        cout << "2. Deposit" << endl;
        cout << "3. Withdraw" << endl;
        cout << "4. Exit" << endl;
        cout << "Selection: ";
       
        if (!(cin >> choice)) {
            cout << "Error: Numeric input required." << endl;
            clearBuffer();
            choice = 0; // Reset
            continue;
        }

        switch (choice) {
            case 1:
                cout << "Current Balance: $" << fixed << setprecision(2) << myAccount.getBalance();
                break;
            case 2:
                cout << "Enter deposit amount: ";
                cin >> amount;
                myAccount.deposit(amount);
                break;
            case 3:
                cout << "Enter withdrawal amount: ";
                cin >> amount;
                myAccount.withdraw(amount);
                break;
            case 4:
                cout << "Thank you for using our ATM. Goodbye!" << endl;
                break;
            default:
                cout << "Invalid selection." << endl;
        }
    } while (choice != 4);

    return 0;
}

Execution Trace (Sample Session)

--- WELCOME TO THE C++ ACADEMIC BANK ---
Enter 4-Digit PIN: 1234

Access Granted. Welcome, Academic User!

--- MAIN MENU ---
1. Check Balance
2. Deposit
3. Withdraw
4. Exit
Selection: 1
Current Balance: $1000.00

--- MAIN MENU ---
Selection: 3
Enter withdrawal amount: 200
[Success] Please collect your $200.00
--- MAIN MENU ---
Selection: 2
Enter deposit amount: -50
[Error] Invalid amount.

Academic "Learning Corner"

  • The Input Fail-Safe: When using cin >> choice, if a user enters a character like 'A', the input stream enters a "fail state." Without cin.clear() and cin.ignore(), the program would enter an infinite loop because the 'A' remains in the buffer.

  • The fixed and setprecision Manipulators: In financial software, precision is critical. By default, C++ might show 1000.5 as 1000.5. Using fixed coupled with setprecision(2) forces the output to 1000.50, meeting standard accounting formats.

MinGW Compatibility: We use std::endl and flush the buffer frequently to ensure the Code::Blocks "Logs & Others" window displays output in real-time, as some versions of the MinGW console are heavily buffered.

eBook ‘16 Intermediate Level C++ Projects’ purchase Link: Google Play Store  || Google Books

eBook ‘16 Intermediate Level C++ Projects’ Promotional Link: 

Level Up from Coder to Architect: Master 16 Intermediate C++ Management Systems 


For all 2026 published articles list: click here

...till the next post, bye-bye & take care

No comments:

Post a Comment