My first project learning to code in C++. A basic menu where the user can make transactions and view the balance.
Includes the standard C++ headers this script needs.
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <iomanip>
#include <thread>
#include <chrono>
Allows prefixes like 'std::' to be ommited.
using namespace std;
using namespace std::chrono_literals;
Define sample account variables.
int main() {
cout << fixed << setprecision(2); /* Rounds all outputs to 2 dec. places */
const string accountName = "john_smith";
const string accountPass = "password";
const short accountPin = 1234;
double accountBalance = 1000;
Prompts the user for username, password, and PIN.
bool logIn = false;
while (logIn == false) {
cout << '\n' << banner("LOG IN");
string inputName;
cout << "\n\nPlease enter your username: ";
cin >> inputName;
if (cin.fail()) cin.clear();
flushLine();
clearLines(1);
string inputPass;
cout << "Please enter your password: ";
cin >> inputPass;
if (cin.fail()) cin.clear();
flushLine();
clearLines(1);
if (inputName == accountName && inputPass == accountPass) {
logIn = pinPrompt(accountPin);
clearLines(3);
} else {
cout << "INCORRECT PASSWORD OR USERNAME.\n";
waitForEnterLogIn();
clearLines(6);
}
}
Functions Used:
/* Handles menu titles to ensure they are all evenly sized */
string banner(const string& title) {
const int width = 53;
string text = " " + title + " ";
int total = width - text.length();
int left = total / 2;
int right = total - left;
return string(left, '*') + text + string(right, '*');
}
/* Clears any inputs left from the last prompt so the next input starts fresh */
void flushLine() {
cin.ignore(numeric_limits::max(), '\n');
}
/* Clears output text to handle menu navigation, status screens, and error messages */
void clearLines(int n) {
for (int i = 0; i < n; i++) {
cout << "\033[A\033[2K";
}
}
/* Handles PIN inputs and limits failed attempts to 3 */
bool pinPrompt(short accountPin) {
const int MAX_ATTEMPTS = 3;
int attempts = 0;
int enteredPin;
while (attempts < MAX_ATTEMPTS)
{
cout << "Please enter your 4-digit pin: ";
cin >> enteredPin;
if (cin.fail()) cin.clear();
flushLine();
clearLines(1);
int temp = enteredPin;
int count = 0;
while (temp > 0) {
temp /= 10;
count++;
}
if (count == 4 && enteredPin == accountPin) return true;
attempts++;
if (count != 4) cout << "ERROR: Invalid PIN digit count. Please enter 4 digits.\n";
else cout << "ERROR: Invalid PIN\n";
if (attempts < MAX_ATTEMPTS) cout << "Remaining Attempts: " << MAX_ATTEMPTS - attempts << '\n';
else cout << "Out of PIN attempts.\n";
waitForEnterPinError();
}
return false;
}
/* Pauses the loop on an incorrect entry */
void waitForEnterLogIn() {
cout << "\nPress Enter to try again...";
cin.get();
}
/* Pauses the PIN prompt loop on an error */
void waitForEnterPinError() {
cout << "\nPress Enter to continue...";
cin.get();
clearLines(4);
}
Generates the main menu and clears the text after user input to make space for the sub-menu.
bool running = true;
while (running) {
short menuSelection;
cout << '\n' << banner("BANK TERMINAL")
<< "\n\nWelcome. Please Select an Account Action:"
<< "\n [1] Deposit\n [2] Withdraw\n [3] Check Balance\n [4] Log Out\n\n"
<< "Selection: ";
cin >> menuSelection;
clearLines(10);
if (cin.fail()) cin.clear();
flushLine();
Case 1: Handles deposits
switch (menuSelection)
{
case 1: {
cout << '\n' << banner("DEPOSIT") << "\n\n";
/* Loops the deposit prompt until the user enters a valid input */
while (true) {
double deposit;
cout << "Enter desired deposit amount (or press 0 to cancel): ";
cin >> deposit;
if (cin.fail()) cin.clear();
flushLine();
clearLines(1);
if (deposit == 0) {
cout << "Deposit cancelled.\n";
waitForEnter();
clearLines(6);
break;
} else if (deposit < 0) {
cout << "ERROR: Deposit amount must be greater than 0.\n"
<< "To withdraw funds, please return to the menu and select '2'.\n";
if (!tryAgain(2)) break;
} else {
accountBalance += deposit;
cout << "SUCCESS! Your deposit was processed and the funds have been added to your account.\n"
<< "\n Your updated account balance is: $" << accountBalance << endl;
if (!tryAgain(3, "Make another deposit")) break;
}
}
break;
}
Functions Used:
/* Pauses loop on cancelled transaction */
void waitForEnter() {
cout << "\nPress Enter to return to the menu...";
cin.get();
}
/* Sub menu for errors and success screens */
/* Prompts user for another transaction, or return to menu */
bool tryAgain(int errorLines, const string& againLabel) {
short choice;
int extra = 0;
while (true)
{
cout << "\nWould you like to...?\n\n"
<< "[1] " << againLabel << "\n"
<< "[2] Return to main menu\n\n"
<< "Selection: ";
cin >> choice;
if (cin.fail()) cin.clear();
flushLine();
if (choice == 1 || choice == 2) {
int back = 7 + extra + errorLines;
clearLines(choice == 1 ? back : back + 3);
return choice == 1;
}
clearLines(7);
cout << "Please select 1 or 2.\n";
extra++;
}
}
Loops a 'Withdraw' menu, subtracts from account balance, and handles errors.
case 2: {
cout << '\n' << banner("WITHDRAW") << "\n\n";
/* Loops the withdraw prompt until the user enters a valid input */
while (true) {
double withdraw;
cout << "Enter desired withdraw amount (or press 0 to cancel): ";
cin >> withdraw;
if (cin.fail()) cin.clear();
flushLine();
clearLines(1);
if (withdraw == 0) {
cout << "Withdraw cancelled.\n";
waitForEnter();
clearLines(6);
break;
} else if (withdraw < 0) {
cout << "ERROR: Withdraw amount must be greater than 0.\n"
<< "To deposit funds, please return to the menu and select '1'.\n";
if (!tryAgain(2)) break;
} else if (withdraw > accountBalance) {
cout << "ERROR: Insufficient funds.\n";
if (!tryAgain(1)) break;
} else {
accountBalance -= withdraw;
cout << "SUCCESS! Your withdraw was processed and the funds have been removed from your account.\n"
<< "\n Your updated account balance is: $" << accountBalance << endl;
if (!tryAgain(3, "Make another withdrawal")) break;
}
}
break;
}
Displays the user's total account balance.
case 3: {
cout << '\n' << banner("BALANCE") << "\n\n";
cout << "ACCOUNT BALANCE: $" << accountBalance << endl;
waitForEnter();
clearLines(6);
break;
}
Exits the loop and ends the code.
case 4:
cout << "\nLogging out...\n\n";
this_thread::sleep_for(2s);
cout << "Goodbye.\n";
running = false;
break;
Handles menu inputs that are invalid.
default:
cout << "Invalid account action. Please choose a number 1-4.\n";
waitForEnter();
clearLines(3);
break;
}
}
}
Complete source code combining all functions, authentication loop, transaction switch statement, and balance management (268 lines).
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <iomanip>
#include <thread>
#include <chrono>
bool pinPrompt(short accountPin);
bool tryAgain(int errorLines, const std::string& againLabel = "Try again");
void waitForEnter();
void waitForEnterLogIn();
void waitForEnterPinError();
void clearLines(int n);
void flushLine();
std::string banner(const std::string& title);
using namespace std;
using namespace std::chrono_literals;
int main() {
cout << fixed << setprecision(2);
const string accountName = "john";
const string accountPass = "password";
const short accountPin = 1234;
double accountBalance = 1000;
bool logIn = false;
while (logIn == false) {
cout << '\n' << banner("LOG IN");
string inputName;
cout << "\n\nPlease enter your username: ";
cin >> inputName;
if (cin.fail()) cin.clear();
flushLine();
clearLines(1);
string inputPass;
cout << "Please enter your password: ";
cin >> inputPass;
if (cin.fail()) cin.clear();
flushLine();
clearLines(1);
if (inputName == accountName && inputPass == accountPass) {
logIn = pinPrompt(accountPin);
clearLines(3);
} else {
cout << "INCORRECT PASSWORD OR USERNAME.\n";
waitForEnterLogIn();
clearLines(6);
}
}
bool running = true;
while (running) {
short menuSelection;
cout << '\n' << banner("BANK TERMINAL")
<< "\n\nWelcome. Please Select an Account Action:"
<< "\n [1] Deposit\n [2] Withdraw\n [3] Check Balance\n [4] Log Out\n\n"
<< "Selection: ";
cin >> menuSelection;
clearLines(10);
if (cin.fail()) cin.clear();
flushLine();
switch (menuSelection)
{
case 1: {
cout << '\n' << banner("DEPOSIT") << "\n\n";
/* Loops the deposit prompt until the user enters a valid input */
while (true) {
double deposit;
cout << "Enter desired deposit amount (or press 0 to cancel): ";
cin >> deposit;
if (cin.fail()) cin.clear();
flushLine();
clearLines(1);
if (deposit == 0) {
cout << "Deposit cancelled.\n";
waitForEnter();
clearLines(6);
break;
} else if (deposit < 0) {
cout << "ERROR: Deposit amount must be greater than 0.\n"
<< "To withdraw funds, please return to the menu and select '2'.\n";
if (!tryAgain(2)) break;
} else {
accountBalance += deposit;
cout << "SUCCESS! Your deposit was processed and the funds have been added to your account.\n"
<< "\n Your updated account balance is: $" << accountBalance << endl;
if (!tryAgain(3, "Make another deposit")) break;
}
}
break;
}
case 2: {
cout << '\n' << banner("WITHDRAW") << "\n\n";
/* Loops the withdraw prompt until the user enters a valid input */
while (true) {
double withdraw;
cout << "Enter desired withdraw amount (or press 0 to cancel): ";
cin >> withdraw;
if (cin.fail()) cin.clear();
flushLine();
clearLines(1);
if (withdraw == 0) {
cout << "Withdraw cancelled.\n";
waitForEnter();
clearLines(6);
break;
} else if (withdraw < 0) {
cout << "ERROR: Withdraw amount must be greater than 0.\n"
<< "To deposit funds, please return to the menu and select '1'.\n";
if (!tryAgain(2)) break;
} else if (withdraw > accountBalance) {
cout << "ERROR: Insufficient funds.\n";
if (!tryAgain(1)) break;
} else {
accountBalance -= withdraw;
cout << "SUCCESS! Your withdraw was processed and the funds have been removed from your account.\n"
<< "\n Your updated account balance is: $" << accountBalance << endl;
if (!tryAgain(3, "Make another withdrawal")) break;
}
}
break;
}
case 3: {
cout << '\n' << banner("BALANCE") << "\n\n";
cout << "ACCOUNT BALANCE: $" << accountBalance << endl;
waitForEnter();
clearLines(6);
break;
}
case 4:
cout << "\nLogging out...\n\n";
this_thread::sleep_for(2s);
cout << "Goodbye.\n";
running = false;
break;
default:
cout << "Invalid account action. Please choose a number 1-4.\n";
waitForEnter();
clearLines(3);
break;
}
}
}
/* ------------ HELPER FUNCTIONS ------------ */
bool pinPrompt(short accountPin) {
const int MAX_ATTEMPTS = 3;
int attempts = 0;
int enteredPin;
while (attempts < MAX_ATTEMPTS)
{
cout << "Please enter your 4-digit pin: ";
cin >> enteredPin;
if (cin.fail()) cin.clear();
flushLine();
clearLines(1);
int temp = enteredPin;
int count = 0;
while (temp > 0) {
temp /= 10;
count++;
}
if (count == 4 && enteredPin == accountPin) return true;
attempts++;
if (count != 4) cout << "ERROR: Invalid PIN digit count. Please enter 4 digits.\n";
else cout << "ERROR: Invalid PIN\n";
if (attempts < MAX_ATTEMPTS) cout << "Remaining Attempts: " << MAX_ATTEMPTS - attempts << '\n';
else cout << "Out of PIN attempts.\n";
waitForEnterPinError();
}
return false;
}
bool tryAgain(int errorLines, const string& againLabel) {
short choice;
int extra = 0;
while (true)
{
cout << "\nWould you like to...?\n\n"
<< "[1] " << againLabel << "\n"
<< "[2] Return to main menu\n\n"
<< "Selection: ";
cin >> choice;
if (cin.fail()) cin.clear();
flushLine();
if (choice == 1 || choice == 2) {
int back = 7 + extra + errorLines;
clearLines(choice == 1 ? back : back + 3);
return choice == 1;
}
clearLines(7);
cout << "Please select 1 or 2.\n";
extra++;
}
}
void waitForEnter() {
cout << "\nPress Enter to return to the menu...";
cin.get();
}
void waitForEnterLogIn() {
cout << "\nPress Enter to try again...";
cin.get();
}
void waitForEnterPinError() {
cout << "\nPress Enter to continue...";
cin.get();
clearLines(4);
}
void clearLines(int n) {
for (int i = 0; i < n; i++) {
cout << "\033[A\033[2K";
}
}
void flushLine() {
cin.ignore(numeric_limits::max(), '\n');
}
string banner(const string& title) {
const int width = 53;
string text = " " + title + " ";
int total = width - text.length();
int left = total / 2;
int right = total - left;
return string(left, '*') + text + string(right, '*');
}