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.
No comments:
Post a Comment