C++ Real-Life Examples

Practical applications of C++ programming concepts in real-world scenarios

Practical Real-World Applications

Real-World C++ Applications

C++ is used in countless real-world applications from operating systems to game engines. Understanding how C++ concepts apply to practical problems is key to mastering the language. Below are real-life examples for each major C++ concept.

Conditional Control Statements

Decision-making in real applications

Traffic Light System

Conditional statements are used in traffic control systems to manage light changes based on time, sensor input, or traffic density.

// Simplified traffic light control
#include <iostream>
using namespace std;

int main() {
    int trafficDensity = 75; // Percentage of road capacity
    bool emergencyVehicle = false;
    
    if (emergencyVehicle) {
        cout << "All lights GREEN for emergency vehicle" << endl;
    } else if (trafficDensity > 80) {
        cout << "Extend GREEN time for main road" << endl;
    } else if (trafficDensity < 20) {
        cout << "Switch to energy-saving mode" << endl;
    } else {
        cout << "Normal operation sequence" << endl;
    }
    
    return 0;
}
User Authentication System

Conditional statements verify user credentials and determine access levels in authentication systems.

// Simple user authentication
#include <iostream>
#include <string>
using namespace std;

int main() {
    string username = "admin";
    string password = "secure123";
    string inputUser, inputPass;
    
    cout << "Enter username: ";
    cin >> inputUser;
    cout << "Enter password: ";
    cin >> inputPass;
    
    if (inputUser == username && inputPass == password) {
        cout << "Access granted! Welcome admin." << endl;
    } else if (inputUser == username) {
        cout << "Incorrect password. Try again." << endl;
    } else {
        cout << "Invalid username." << endl;
    }
    
    return 0;
}

Loops

Repetitive tasks in applications

Digital Clock Simulation

Loops are essential for continuously running systems like clocks, monitoring tools, and servers.

// Simplified digital clock using loops
#include <iostream>
#include <unistd.h> // For sleep function
using namespace std;

int main() {
    int hours = 0, minutes = 0, seconds = 0;
    
    // Simulate 24 hours of clock time
    for (hours = 0; hours < 24; hours++) {
        for (minutes = 0; minutes < 60; minutes++) {
            for (seconds = 0; seconds < 60; seconds++) {
                // Clear screen (system dependent)
                cout << "\033[2J\033[1;1H"; // ANSI escape codes
                cout << "Digital Clock Simulation" << endl;
                cout << "Time: " << hours << ":" << minutes << ":" << seconds << endl;
                
                sleep(1); // Wait for 1 second
            }
        }
    }
    
    return 0;
}
Data Processing

Loops process large datasets, such as analyzing sensor readings or customer records.

// Processing sensor data with loops
#include <iostream>
using namespace std;

int main() {
    const int NUM_SENSORS = 10;
    double sensorReadings[NUM_SENSORS] = {23.5, 24.1, 22.8, 25.3, 23.9, 
                                      24.8, 22.5, 23.7, 24.5, 23.2};
    double total = 0.0, average;
    
    // Calculate average temperature
    for (int i = 0; i < NUM_SENSORS; i++) {
        total += sensorReadings[i];
    }
    average = total / NUM_SENSORS;
    
    cout << "Average temperature: " << average << "°C" << endl;
    
    // Identify sensors with above-average readings
    cout << "Sensors above average: ";
    for (int i = 0; i < NUM_SENSORS; i++) {
        if (sensorReadings[i] > average) {
            cout << "Sensor " << i+1 << " (" << sensorReadings[i] << "), ";
        }
    }
    cout << endl;
    
    return 0;
}

Arrays

Storing and processing collections of data

Student Grade Management

Arrays store and process multiple values, such as student grades in a classroom.

// Student grade management using arrays
#include <iostream>
using namespace std;

int main() {
    const int NUM_STUDENTS = 5;
    string students[NUM_STUDENTS] = {"Alice", "Bob", "Charlie", "Diana", "Evan"};
    int grades[NUM_STUDENTS] = {85, 92, 78, 88, 95};
    
    // Calculate class average
    int total = 0;
    for (int i = 0; i < NUM_STUDENTS; i++) {
        total += grades[i];
    }
    double average = static_cast<double>(total) / NUM_STUDENTS;
    
    // Find highest and lowest grades
    int highest = grades[0], lowest = grades[0];
    string topStudent = students[0], bottomStudent = students[0];
    
    for (int i = 1; i < NUM_STUDENTS; i++) {
        if (grades[i] > highest) {
            highest = grades[i];
            topStudent = students[i];
        }
        if (grades[i] < lowest) {
            lowest = grades[i];
            bottomStudent = students[i];
        }
    }
    
    // Display results
    cout << "Class Grade Report" << endl;
    cout << "Average grade: " << average << endl;
    cout << "Highest grade: " << highest << " by " << topStudent << endl;
    cout << "Lowest grade: " << lowest << " by " << bottomStudent << endl;
    
    return 0;
}
Inventory Management

Arrays manage product inventories in retail systems.

// Simple inventory management system
#include <iostream>
#include <string>
using namespace std;

int main() {
    const int MAX_PRODUCTS = 100;
    string products[MAX_PRODUCTS];
    int quantities[MAX_PRODUCTS];
    int productCount = 0;
    
    // Add some sample products
    products[productCount] = "Laptop";
    quantities[productCount] = 15;
    productCount++;
    
    products[productCount] = "Mouse";
    quantities[productCount] = 42;
    productCount++;
    
    products[productCount] = "Keyboard";
    quantities[productCount] = 25;
    productCount++;
    
    // Display inventory
    cout << "Current Inventory:" << endl;
    for (int i = 0; i < productCount; i++) {
        cout << products[i] << ": " << quantities[i] << " units" << endl;
    }
    
    // Check for low stock items
    cout << "\nLow Stock Alert:" << endl;
    bool lowStockFound = false;
    for (int i = 0; i < productCount; i++) {
        if (quantities[i] < 20) {
            cout << "LOW: " << products[i] << " (only " << quantities[i] << " left)" << endl;
            lowStockFound = true;
        }
    }
    
    if (!lowStockFound) {
        cout << "No low stock items." << endl;
    }
    
    return 0;
}

Strings

Text processing in applications

Text Analysis Tool

Strings process and analyze text data, such as counting words or finding patterns.

// Simple text analysis tool
#include <iostream>
#include <string>
#include <cctype> // For character functions
using namespace std;

int main() {
    string text = "C++ is a powerful programming language. "
                 "It is widely used for system software, game development, "
                 "and performance-critical applications.";
    
    // Count words
    int wordCount = 0;
    bool inWord = false;
    
    for (char c : text) {
        if (isalpha(c)) {
            if (!inWord) {
                wordCount++;
                inWord = true;
            }
        } else {
            inWord = false;
        }
    }
    
    // Count sentences
    int sentenceCount = 0;
    for (char c : text) {
        if (c == '.' || c == '!' || c == '?') {
            sentenceCount++;
        }
    }
    
    // Find occurrences of "C++"
    int cppCount = 0;
    size_t pos = text.find("C++");
    while (pos != string::npos) {
        cppCount++;
        pos = text.find("C++", pos + 1);
    }
    
    // Display analysis results
    cout << "Text Analysis Results:" << endl;
    cout << "Total characters: " << text.length() << endl;
    cout << "Word count: " << wordCount << endl;
    cout << "Sentence count: " << sentenceCount << endl;
    cout << "Occurrences of 'C++': " << cppCount << endl;
    
    return 0;
}
Password Strength Checker

String operations validate and check password strength based on various criteria.

// Password strength checker
#include <iostream>
#include <string>
#include <cctype>
using namespace std;

bool isStrongPassword(const string& password) {
    bool hasUpper = false, hasLower = false;
    bool hasDigit = false, hasSpecial = false;
    
    if (password.length() < 8) {
        cout << "Password must be at least 8 characters long." << endl;
        return false;
    }
    
    for (char c : password) {
        if (isupper(c)) hasUpper = true;
        else if (islower(c)) hasLower = true;
        else if (isdigit(c)) hasDigit = true;
        else hasSpecial = true;
    }
    
    if (!hasUpper) {
        cout << "Password must contain at least one uppercase letter." << endl;
        return false;
    }
    if (!hasLower) {
        cout << "Password must contain at least one lowercase letter." << endl;
        return false;
    }
    if (!hasDigit) {
        cout << "Password must contain at least one digit." << endl;
        return false;
    }
    if (!hasSpecial) {
        cout << "Password must contain at least one special character." << endl;
        return false;
    }
    
    return true;
}

int main() {
    string password;
    cout << "Enter a password to check: ";
    cin >> password;
    
    if (isStrongPassword(password)) {
        cout << "Password is strong!" << endl;
    } else {
        cout << "Password is weak. Please try again." << endl;
    }
    
    return 0;
}

Functions and Recursion

Modular programming and recursive algorithms

Banking System

Functions create modular banking operations like deposits, withdrawals, and balance checks.

// Simple banking system using functions
#include <iostream>
using namespace std;

// Function declarations
void showMenu();
void deposit(double &balance);
void withdraw(double &balance);
void showBalance(double balance);

int main() {
    double balance = 0.0;
    int choice;
    
    do {
        showMenu();
        cin >> choice;
        
        switch (choice) {
            case 1:
                deposit(balance);
                break;
            case 2:
                withdraw(balance);
                break;
            case 3:
                showBalance(balance);
                break;
            case 4:
                cout << "Thank you for banking with us!" << endl;
                break;
            default:
                cout << "Invalid choice. Please try again." << endl;
        }
    } while (choice != 4);
    
    return 0;
}

void showMenu() {
    cout << "\n*** Banking Menu ***" << endl;
    cout << "1. Deposit Money" << endl;
    cout << "2. Withdraw Money" << endl;
    cout << "3. Show Balance" << endl;
    cout << "4. Exit" << endl;
    cout << "Enter your choice: ";
}

void deposit(double &balance) {
    double amount;
    cout << "Enter amount to deposit: $";
    cin >> amount;
    
    if (amount > 0) {
        balance += amount;
        cout << "Successfully deposited $" << amount << endl;
    } else {
        cout << "Invalid amount. Deposit failed." << endl;
    }
}

void withdraw(double &balance) {
    double amount;
    cout << "Enter amount to withdraw: $";
    cin >> amount;
    
    if (amount > 0 && amount <= balance) {
        balance -= amount;
        cout << "Successfully withdrew $" << amount << endl;
    } else if (amount > balance) {
        cout << "Insufficient funds. Withdrawal failed." << endl;
    } else {
        cout << "Invalid amount. Withdrawal failed." << endl;
    }
}

void showBalance(double balance) {
    cout << "Your current balance is: $" << balance << endl;
}
File System Navigation

Recursion navigates hierarchical structures like file systems or organizational charts.

// Simulating file system navigation with recursion
#include <iostream>
#include <vector>
#include <string>
using namespace std;

// Structure to represent a file system node
struct FileSystemNode {
    string name;
    bool isDirectory;
    vector<FileSystemNode*> children;
};

// Recursive function to display file system structure
void displayFileSystem(const FileSystemNode* node, int depth = 0) {
    if (!node) return;
    
    // Indent based on depth
    for (int i = 0; i < depth; i++) {
        cout << "  ";
    }
    
    // Display node name with appropriate icon
    if (node->isDirectory) {
        cout << "[D] " << node->name << "/" << endl;
    } else {
        cout << "[F] " << node->name << endl;
    }
    
    // Recursively display children
    for (const auto& child : node->children) {
        displayFileSystem(child, depth + 1);
    }
}

int main() {
    // Create a sample file system structure
    FileSystemNode root{"C:", true, {}};
    FileSystemNode programs{"Program Files", true, {}};
    FileSystemNode users{"Users", true, {}};
    FileSystemNode documents{"Documents", true, {}};
    FileSystemNode photos{"Photos", true, {}};
    
    FileSystemNode app1{"App1", true, {}};
    FileSystemNode app2{"App2", true, {}};
    
    FileSystemNode exe1{"app1.exe", false, {}};
    FileSystemNode exe2{"app2.exe", false, {}};
    FileSystemNode readme{"readme.txt", false, {}};
    FileSystemNode vacation{"vacation.jpg", false, {}};
    FileSystemNode report{"report.docx", false, {}};
    
    // Build the file system hierarchy
    app1.children.push_back(&exe1);
    app2.children.push_back(&exe2);
    programs.children.push_back(&app1);
    programs.children.push_back(&app2);
    programs.children.push_back(&readme);
    
    photos.children.push_back(&vacation);
    documents.children.push_back(&report);
    users.children.push_back(&documents);
    users.children.push_back(&photos);
    
    root.children.push_back(&programs);
    root.children.push_back(&users);
    
    // Display the file system structure
    cout << "File System Structure:" << endl;
    displayFileSystem(&root);
    
    return 0;
}

Pointers and Dynamic Memory

Memory management and efficient data handling

Image Processing

Pointers and dynamic memory efficiently handle large data like image pixels.

// Image processing using dynamic memory allocation
#include <iostream>
#include <cstdlib> // For rand()
using namespace std;

struct Pixel {
    unsigned char red;
    unsigned char green;
    unsigned char blue;
};

class Image {
private:
    int width;
    int height;
    Pixel** pixels; // 2D array of pixels
    
public:
    Image(int w, int h) : width(w), height(h) {
        // Dynamically allocate memory for the image
        pixels = new Pixel*[height];
        for (int i = 0; i < height; i++) {
            pixels[i] = new Pixel[width];
        }
    }
    
    ~Image() {
        // Free dynamically allocated memory
        for (int i = 0; i < height; i++) {
            delete[] pixels[i];
        }
        delete[] pixels;
    }
    
    void generateRandomImage() {
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                pixels[y][x].red = rand() % 256;
                pixels[y][x].green = rand() % 256;
                pixels[y][x].blue = rand() % 256;
            }
        }
    }
    
    void convertToGrayscale() {
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                unsigned char gray = (
                    pixels[y][x].red * 0.3 + 
                    pixels[y][x].green * 0.59 + 
                    pixels[y][x].blue * 0.11
                );
                pixels[y][x].red = gray;
                pixels[y][x].green = gray;
                pixels[y][x].blue = gray;
            }
        }
    }
    
    void displayImageInfo() {
        cout << "Image Information:" << endl;
        cout << "Width: " << width << " pixels" << endl;
        cout << "Height: " << height << " pixels" << endl;
        cout << "Total pixels: " << width * height << endl;
        cout << "Memory used: " << width * height * sizeof(Pixel) << " bytes" << endl;
    }
};

int main() {
    // Create a new image
    Image myImage(800, 600);
    myImage.displayImageInfo();
    
    // Generate a random colorful image
    myImage.generateRandomImage();
    cout << "Generated random colorful image." << endl;
    
    // Convert to grayscale
    myImage.convertToGrayscale();
    cout << "Converted image to grayscale." << endl;
    
    // Image object will be automatically destroyed when it goes out of scope
    // Destructor will free the dynamically allocated memory
    
    return 0;
}
Linked List Implementation

Pointers create dynamic data structures like linked lists for efficient data management.

// Linked list implementation using pointers
#include <iostream>
using namespace std;

struct Node {
    int data;
    Node* next;
};

class LinkedList {
private:
    Node* head;
    
public:
    LinkedList() : head(nullptr) {}
    
    ~LinkedList() {
        // Free all allocated memory when the list is destroyed
        Node* current = head;
        while (current != nullptr) {
            Node* next = current->next;
            delete current;
            current = next;
        }
    }
    
    void append(int value) {
        Node* newNode = new Node{value, nullptr};
        
        if (head == nullptr) {
            head = newNode;
        } else {
            Node* current = head;
            while (current->next != nullptr) {
                current = current->next;
            }
            current->next = newNode;
        }
    }
    
    void prepend(int value) {
        Node* newNode = new Node{value, head};
        head = newNode;
    }
    
    void remove(int value) {
        if (head == nullptr) return;
        
        if (head->data == value) {
            Node* toDelete = head;
            head = head->next;
            delete toDelete;
            return;
        }
        
        Node* current = head;
        while (current->next != nullptr) {
            if (current->next->data == value) {
                Node* toDelete = current->next;
                current->next = current->next->next;
                delete toDelete;
                return;
            }
            current = current->next;
        }
    }
    
    void display() {
        Node* current = head;
        cout << "Linked List: ";
        while (current != nullptr) {
            cout << current->data;
            if (current->next != nullptr) {
                cout << " -> ";
            }
            current = current->next;
        }
        cout << " -> NULL" << endl;
    }
};

int main() {
    LinkedList list;
    
    // Add elements to the list
    list.append(10);
    list.append(20);
    list.append(30);
    list.prepend(5);
    
    list.display(); // Output: 5 -> 10 -> 20 -> 30 -> NULL
    
    // Remove an element
    list.remove(20);
    list.display(); // Output: 5 -> 10 -> 30 -> NULL
    
    // Add more elements
    list.append(40);
    list.append(50);
    list.display(); // Output: 5 -> 10 -> 30 -> 40 -> 50 -> NULL
    
    // The destructor will automatically free all memory when the list goes out of scope
    
    return 0;
}

Object-Oriented Programming (OOP)

Modeling real-world entities as objects

Bank Account System

OOP models real-world entities like bank accounts with properties and behaviors.

// Bank account system using OOP
#include <iostream>
#include <string>
using namespace std;

class BankAccount {
private:
    string accountNumber;
    string accountHolder;
    double balance;
    static int totalAccounts; // Static member to track total accounts
    
public:
    BankAccount(const string& number, const string& holder, double initialBalance = 0.0)
        : accountNumber(number), accountHolder(holder), balance(initialBalance) {
        totalAccounts++;
    }
    
    ~BankAccount() {
        totalAccounts--;
    }
    
    void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            cout << "Deposited $" << amount << ". New balance: $" << balance << endl;
        } else {
            cout << "Invalid deposit amount." << endl;
        }
    }
    
    void withdraw(double amount) {
        if (amount > 0 && amount <= balance) {
            balance -= amount;
            cout << "Withdrew $" << amount << ". New balance: $" << balance << endl;
        } else if (amount > balance) {
            cout << "Insufficient funds. Withdrawal failed." << endl;
        } else {
            cout << "Invalid withdrawal amount." << endl;
        }
    }
    
    void display() const {
        cout << "Account Number: " << accountNumber << endl;
        cout << "Account Holder: " << accountHolder << endl;
        cout << "Balance: $" << balance << endl;
    }
    
    static int getTotalAccounts() {
        return totalAccounts;
    }
};

// Initialize static member
int BankAccount::totalAccounts = 0;

class SavingsAccount : public BankAccount {
private:
    double interestRate;
    
public:
    SavingsAccount(const string& number, const string& holder, 
                  double initialBalance, double rate)
        : BankAccount(number, holder, initialBalance), interestRate(rate) {}
    
    void applyInterest() {
        double interest = getBalance() * interestRate / 100;
        deposit(interest);
        cout << "Interest applied: $" << interest << endl;
    }
    
    double getBalance() const {
        // In a real implementation, we would have a getter for balance
        // For simplicity, we'll return a fixed value here
        return 1000; // Placeholder
    }
};

int main() {
    // Create a regular bank account
    BankAccount account("12345678", "John Doe", 500.0);
    account.display();
    account.deposit(250.0);
    account.withdraw(100.0);
    
    cout << endl;
    
    // Create a savings account
    SavingsAccount savings("87654321", "Jane Smith", 1000.0, 2.5);
    savings.display();
    savings.applyInterest();
    
    cout << endl;
    cout << "Total bank accounts: " << BankAccount::getTotalAccounts() << endl;
    
    return 0;
}
E-Commerce Product System

OOP models e-commerce products with inheritance for different product types.

// E-commerce product system using OOP and inheritance
#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Product {
protected:
    string id;
    string name;
    double price;
    int stock;
    
public:
    Product(const string& productId, const string& productName, 
            double productPrice, int productStock)
        : id(productId), name(productName), price(productPrice), stock(productStock) {}
    
    virtual ~Product() {}
    
    virtual void display() const {
        cout << "ID: " << id << ", Name: " << name 
             << ", Price: $" << price << ", Stock: " << stock;
    }
    
    virtual double calculateDiscount() const {
        return 0.0; // No discount by default
    }
    
    bool purchase(int quantity) {
        if (quantity <= stock) {
            stock -= quantity;
            return true;
        }
        return false;
    }
    
    string getId() const { return id; }
    string getName() const { return name; }
    double getPrice() const { return price; }
    int getStock() const { return stock; }
};

class Book : public Product {
private:
    string author;
    string isbn;
    
public:
    Book(const string& productId, const string& productName, 
         double productPrice, int productStock,
         const string& bookAuthor, const string& bookIsbn)
        : Product(productId, productName, productPrice, productStock), 
          author(bookAuthor), isbn(bookIsbn) {}
    
    void display() const override {
        Product::display();
        cout << ", Author: " << author << ", ISBN: " << isbn;
    }
    
    double calculateDiscount() const override {
        // 10% discount on books
        return price * 0.1;
    }
};

class Electronics : public Product {
private:
    string brand;
    string model;
    int warrantyMonths;
    
public:
    Electronics(const string& productId, const string& productName, 
                double productPrice, int productStock,
                const string& deviceBrand, const string& deviceModel, 
                int warranty)
        : Product(productId, productName, productPrice, productStock), 
          brand(deviceBrand), model(deviceModel), warrantyMonths(warranty) {}
    
    void display() const override {
        Product::display();
        cout << ", Brand: " << brand << ", Model: " << model 
             << ", Warranty: " << warrantyMonths << " months";
    }
    
    double calculateDiscount() const override {
        // 15% discount on electronics
        return price * 0.15;
    }
};

class ShoppingCart {
private:
    vector<Product*> items;
    vector<int> quantities;
    
public:
    ~ShoppingCart() {
        // Note: We're not deleting the products as they are owned by the inventory
        // In a real system, we would have proper memory management
    }
    
    void addItem(Product* product, int quantity = 1) {
        if (product->purchase(quantity)) {
            items.push_back(product);
            quantities.push_back(quantity);
            cout << "Added " << quantity << " of " << product->getName() << " to cart." << endl;
        } else {
            cout << "Not enough stock for " << product->getName() << endl;
        }
    }
    
    double calculateTotal() const {
        double total = 0.0;
        for (size_t i = 0; i < items.size(); i++) {
            double discountedPrice = items[i]->getPrice() - items[i]->calculateDiscount();
            total += discountedPrice * quantities[i];
        }
        return total;
    }
    
    void displayCart() const {
        cout << "Shopping Cart Contents:" << endl;
        for (size_t i = 0; i < items.size(); i++) {
            cout << quantities[i] << " x " << items[i]->getName() 
                 << " ($" << items[i]->getPrice() - items[i]->calculateDiscount() << " each)" << endl;
        }
        cout << "Total: $" << calculateTotal() << endl;
    }
};

int main() {
    // Create some products
    Book book("B001", "C++ Programming Guide", 45.99, 10, "John Doe", "978-0123456789");
    Electronics laptop("E001", "Gaming Laptop", 1299.99, 5, "TechBrand", "XPS-15", 24);
    
    // Display product information
    cout << "Product Information:" << endl;
    book.display();
    cout << endl;
    laptop.display();
    cout << endl << endl;
    
    // Create a shopping cart and add items
    ShoppingCart cart;
    cart.addItem(&book, 2);
    cart.addItem(&laptop, 1);
    
    cout << endl;
    cart.displayCart();
    
    return 0;
}

Standard Template Library (STL)

Using built-in data structures and algorithms

Employee Management System

STL containers manage collections of data like employee records.

// Employee management system using STL
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <map>
using namespace std;

struct Employee {
    int id;
    string name;
    string department;
    double salary;
    
    Employee(int empId, const string& empName, 
             const string& empDept, double empSalary)
        : id(empId), name(empName), department(empDept), salary(empSalary) {}
    
    void display() const {
        cout << "ID: " << id << ", Name: " << name 
             << ", Department: " << department 
             << ", Salary: $" << salary << endl;
    }
};

class EmployeeManager {
private:
    vector<Employee> employees;
    map<string, int> departmentCount;
    
public:
    void addEmployee(const Employee& emp) {
        employees.push_back(emp);
        departmentCount[emp.department]++;
    }
    
    void displayAllEmployees() const {
        cout << "All Employees:" << endl;
        for (const auto& emp : employees) {
            emp.display();
        }
    }
    
    void sortEmployeesByName() {
        sort(employees.begin(), employees.end(), 
            [](const Employee& a, const Employee& b) {
                return a.name < b.name;
            });
    }
    
    void sortEmployeesBySalary() {
        sort(employees.begin(), employees.end(), 
            [](const Employee& a, const Employee& b) {
                return a.salary > b.salary; // Descending order
            });
    }
    
    vector<Employee> findEmployeesByDepartment(const string& department) const {
        vector<Employee> result;
        copy_if(employees.begin(), employees.end(), back_inserter(result),
            [&department](const Employee& emp) {
                return emp.department == department;
            });
        return result;
    }
    
    void displayDepartmentStats() const {
        cout << "Department Statistics:" << endl;
        for (const auto& pair : departmentCount) {
            cout << pair.first << ": " << pair.second << " employees" << endl;
        }
    }
    
    double calculateTotalSalary() const {
        double total = 0.0;
        for (const auto& emp : employees) {
            total += emp.salary;
        }
        return total;
    }
    
    double calculateAverageSalary() const {
        if (employees.empty()) return 0.0;
        return calculateTotalSalary() / employees.size();
    }
};

int main() {
    EmployeeManager manager;
    
    // Add employees
    manager.addEmployee(Employee(101, "Alice Johnson", "Engineering", 75000));
    manager.addEmployee(Employee(102, "Bob Smith", "Marketing", 65000));
    manager.addEmployee(Employee(103, "Charlie Brown", "Engineering", 82000));
    manager.addEmployee(Employee(104, "Diana Prince", "HR", 60000));
    manager.addEmployee(Employee(105, "Evan Wright", "Marketing", 58000));
    
    // Display all employees
    manager.displayAllEmployees();
    cout << endl;
    
    // Display department statistics
    manager.displayDepartmentStats();
    cout << endl;
    
    // Display salary information
    cout << "Total salary expenditure: $" << manager.calculateTotalSalary() << endl;
    cout << "Average salary: $" << manager.calculateAverageSalary() << endl;
    cout << endl;
    
    // Find and display engineering employees
    vector<Employee> engineering = manager.findEmployeesByDepartment("Engineering");
    cout << "Engineering Department Employees:" << endl;
    for (const auto& emp : engineering) {
        emp.display();
    }
    cout << endl;
    
    // Sort by salary and display
    manager.sortEmployeesBySalary();
    cout << "Employees sorted by salary (highest first):" << endl;
    manager.displayAllEmployees();
    
    return 0;
}
Task Scheduler

STL containers and algorithms manage and prioritize tasks.

// Task scheduler using STL priority queue
#include <iostream>
#include <queue>
#include <string>
#include <vector>
#include <ctime>
using namespace std;

enum class Priority { LOW, MEDIUM, HIGH };

struct Task {
    int id;
    string description;
    Priority priority;
    time_t addedTime;
    
    Task(int taskId, const string& desc, Priority prio)
        : id(taskId), description(desc), priority(prio) {
        addedTime = time(nullptr);
    }
    
    bool operator<(const Task& other) const {
        // Higher priority tasks come first
        if (priority != other.priority) {
            return priority < other.priority;
        }
        // If same priority, earlier tasks come first
        return addedTime > other.addedTime;
    }
    
    void display() const {
        string prioStr;
        switch (priority) {
            case Priority::LOW: prioStr = "LOW"; break;
            case Priority::MEDIUM: prioStr = "MEDIUM"; break;
            case Priority::HIGH: prioStr = "HIGH"; break;
        }
        cout << "Task #" << id << ": " << description 
             << " [Priority: " << prioStr << "]" << endl;
    }
};

class TaskScheduler {
private:
    priority_queue<Task> tasks;
    int nextId;
    
public:
    TaskScheduler() : nextId(1) {}
    
    void addTask(const string& description, Priority priority) {
        tasks.push(Task(nextId++, description, priority));
        cout << "Added task: " << description << endl;
    }
    
    void processNextTask() {
        if (tasks.empty()) {
            cout << "No tasks to process." << endl;
            return;
        }
        
        Task nextTask = tasks.top();
        tasks.pop();
        
        cout << "Processing: ";
        nextTask.display();
    }
    
    void displayPendingTasks() const {
        // Create a copy of the priority queue to display without modifying
        priority_queue<Task> temp = tasks;
        
        if (temp.empty()) {
            cout << "No pending tasks." << endl;
            return;
        }
        
        cout << "Pending Tasks (in priority order):" << endl;
        while (!temp.empty()) {
            temp.top().display();
            temp.pop();
        }
    }
    
    int getPendingTaskCount() const {
        return tasks.size();
    }
};

int main() {
    TaskScheduler scheduler;
    
    // Add some tasks with different priorities
    scheduler.addTask("Fix critical security bug", Priority::HIGH);
    scheduler.addTask("Prepare monthly report", Priority::MEDIUM);
    scheduler.addTask("Update documentation", Priority::LOW);
    scheduler.addTask("Respond to customer emergency", Priority::HIGH);
    scheduler.addTask("Team lunch planning", Priority::LOW);
    
    cout << endl;
    scheduler.displayPendingTasks();
    
    cout << endl << "Processing tasks..." << endl;
    while (scheduler.getPendingTaskCount() > 0) {
        scheduler.processNextTask();
    }
    
    return 0;
}

File Handling

Reading from and writing to files

Student Records System

File handling persists student data between program executions.

// Student records system with file handling
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;

struct Student {
    int id;
    string name;
    double gpa;
    
    Student(int studentId, const string& studentName, double studentGpa)
        : id(studentId), name(studentName), gpa(studentGpa) {}
    
    void display() const {
        cout << "ID: " << id << ", Name: " << name << ", GPA: " << gpa << endl;
    }
};

class StudentManager {
private:
    vector<Student> students;
    string filename;
    
public:
    StudentManager(const string& file) : filename(file) {
        loadFromFile();
    }
    
    ~StudentManager() {
        saveToFile();
    }
    
    void addStudent(const Student& student) {
        students.push_back(student);
    }
    
    void displayAllStudents() const {
        if (students.empty()) {
            cout << "No students in records." << endl;
            return;
        }
        
        cout << "Student Records:" << endl;
        for (const auto& student : students) {
            student.display();
        }
    }
    
    void loadFromFile() {
        ifstream file(filename);
        if (!file.is_open()) {
            cout << "Could not open file for reading. Starting with empty records." << endl;
            return;
        }
        
        students.clear();
        int id;
        string name;
        double gpa;
        
        while (file >> id) {
            file.ignore(); // Ignore the space after ID
            getline(file, name);
            file >> gpa;
            students.emplace_back(id, name, gpa);
        }
        
        file.close();
        cout << "Loaded " << students.size() << " student records from file." << endl;
    }
    
    void saveToFile() const {
        ofstream file(filename);
        if (!file.is_open()) {
            cerr << "Error: Could not open file for writing." << endl;
            return;
        }
        
        for (const auto& student : students) {
            file << student.id << " " << student.name << "\n" << student.gpa << "\n";
        }
        
        file.close();
        cout << "Saved " << students.size() << " student records to file." << endl;
    }
    
    vector<Student> findStudentsByGPA(double minGPA) const {
        vector<Student> result;
        for (const auto& student : students) {
            if (student.gpa >= minGPA) {
                result.push_back(student);
            }
        }
        return result;
    }
};

int main() {
    StudentManager manager("students.txt");
    
    // Add some students
    manager.addStudent(Student(1001, "Alice Johnson", 3.8));
    manager.addStudent(Student(1002, "Bob Smith", 3.2));
    manager.addStudent(Student(1003, "Charlie Brown", 3.9));
    manager.addStudent(Student(1004, "Diana Prince", 3.5));
    
    // Display all students
    manager.displayAllStudents();
    cout << endl;
    
    // Find students with GPA >= 3.5
    vector<Student> highAchievers = manager.findStudentsByGPA(3.5);
    cout << "High Achievers (GPA >= 3.5):" << endl;
    for (const auto& student : highAchievers) {
        student.display();
    }
    
    // The destructor will automatically save to file
    
    return 0;
}
Configuration File Parser

File handling reads and writes configuration settings for applications.

// Configuration file parser using file handling
#include <iostream>
#include <fstream>
#include <string>
#include <map>
using namespace std;

class ConfigParser {
private:
    map<string, string> settings;
    string filename;
    
    void trim(string& str) {
        // Remove leading and trailing whitespace
        size_t start = str.find_first_not_of(" \t\n\r\f\v");
        size_t end = str.find_last_not_of(" \t\n\r\f\v");
        
        if (start == string::npos) {
            str = "";
        } else {
            str = str.substr(start, end - start + 1);
        }
    }
    
public:
    ConfigParser(const string& file) : filename(file) {
        loadConfig();
    }
    
    void loadConfig() {
        ifstream file(filename);
        if (!file.is_open()) {
            cerr << "Warning: Could not open config file: " << filename << endl;
            return;
        }
        
        string line;
        while (getline(file, line)) {
            // Skip empty lines and comments
            if (line.empty() || line[0] == '#') {
                continue;
            }
            
            // Find the equals sign
            size_t equalsPos = line.find('=');
            if (equalsPos == string::npos) {
                continue; // Invalid line
            }
            
            // Extract key and value
            string key = line.substr(0, equalsPos);
            string value = line.substr(equalsPos + 1);
            
            // Trim whitespace
            trim(key);
            trim(value);
            
            // Store in map
            settings[key] = value;
        }
        
        file.close();
        cout << "Loaded " << settings.size() << " configuration settings." << endl;
    }
    
    void saveConfig() const {
        ofstream file(filename);
        if (!file.is_open()) {
            cerr << "Error: Could not open config file for writing: " << filename << endl;
            return;
        }
        
        file << "# Application Configuration File" << endl;
        file << "# This file is auto-generated" << endl << endl;
        
        for (const auto& pair : settings) {
            file << pair.first << " = " << pair.second << endl;
        }
        
        file.close();
        cout << "Saved configuration to file." << endl;
    }
    
    string getString(const string& key, const string& defaultValue = "") {
        auto it = settings.find(key);
        if (it != settings.end()) {
            return it->second;
        }
        return defaultValue;
    }
    
    int getInt(const string& key, int defaultValue = 0) {
        string value = getString(key);
        if (value.empty()) {
            return defaultValue;
        }
        return stoi(value);
    }
    
    double getDouble(const string& key, double defaultValue = 0.0) {
        string value = getString(key);
        if (value.empty()) {
            return defaultValue;
        }
        return stod(value);
    }
    
    bool getBool(const string& key, bool defaultValue = false) {
        string value = getString(key);
        if (value.empty()) {
            return defaultValue;
        }
        return (value == "true" || value == "1" || value == "yes");
    }
    
    void setString(const string& key, const string& value) {
        settings[key] = value;
    }
    
    void setInt(const string& key, int value) {
        settings[key] = to_string(value);
    }
    
    void setDouble(const string& key, double value) {
        settings[key] = to_string(value);
    }
    
    void setBool(const string& key, bool value) {
        settings[key] = value ? "true" : "false";
    }
    
    void displayAllSettings() const {
        cout << "Current Configuration:" << endl;
        for (const auto& pair : settings) {
            cout << pair.first << " = " << pair.second << endl;
        }
    }
};

int main() {
    ConfigParser config("app.config");
    
    // Display current settings
    config.displayAllSettings();
    cout << endl;
    
    // Get some values
    string appName = config.getString("app_name", "MyApp");
    int maxUsers = config.getInt("max_users", 10);
    double timeout = config.getDouble("timeout", 30.0);
    bool logging = config.getBool("enable_logging", true);
    
    cout << "Application Name: " << appName << endl;
    cout << "Max Users: " << maxUsers << endl;
    cout << "Timeout: " << timeout << " seconds" << endl;
    cout << "Logging Enabled: " << (logging ? "Yes" : "No") << endl;
    cout << endl;
    
    // Update some settings
    config.setInt("max_users", 25);
    config.setDouble("timeout", 45.5);
    config.setBool("enable_logging", false);
    
    // Save the updated configuration
    config.saveConfig();
    
    return 0;
}

Exception Handling

Graceful error handling in applications

Bank Transaction System

Exception handling manages errors in financial transactions.

// Bank transaction system with exception handling
#include <iostream>
#include <stdexcept>
#include <string>
using namespace std;

// Custom exception classes
class InsufficientFundsException : public exception {
private:
    double balance;
    double amount;
    
public:
    InsufficientFundsException(double currentBalance, double withdrawalAmount)
        : balance(currentBalance), amount(withdrawalAmount) {}
    
    const char* what() const noexcept override {
        return "Error: Insufficient funds for withdrawal";
    }
    
    double getBalance() const { return balance; }
    double getAmount() const { return amount; }
};

class InvalidAmountException : public exception {
public:
    const char* what() const noexcept override {
        return "Error: Invalid amount specified";
    }
};

class AccountNotFoundException : public exception {
private:
    string accountNumber;
    
public:
    AccountNotFoundException(const string& accNumber)
        : accountNumber(accNumber) {}
    
    const char* what() const noexcept override {
        return "Error: Account not found";
    }
    
    string getAccountNumber() const { return accountNumber; }
};

class BankAccount {
private:
    string accountNumber;
    string accountHolder;
    double balance;
    
public:
    BankAccount(const string& accNumber, const string& holder, double initialBalance = 0.0)
        : accountNumber(accNumber), accountHolder(holder), balance(initialBalance) {
        if (initialBalance < 0) {
            throw InvalidAmountException();
        }
    }
    
    void deposit(double amount) {
        if (amount <= 0) {
            throw InvalidAmountException();
        }
        balance += amount;
        cout << "Deposited $" << amount << ". New balance: $" << balance << endl;
    }
    
    void withdraw(double amount) {
        if (amount <= 0) {
            throw InvalidAmountException();
        }
        
        if (amount > balance) {
            throw InsufficientFundsException(balance, amount);
        }
        
        balance -= amount;
        cout << "Withdrew $" << amount << ". New balance: $" << balance << endl;
    }
    
    void transferTo(BankAccount& recipient, double amount) {
        if (amount <= 0) {
            throw InvalidAmountException();
        }
        
        if (amount > balance) {
            throw InsufficientFundsException(balance, amount);
        }
        
        // Withdraw from this account
        balance -= amount;
        
        // Deposit to recipient account
        recipient.balance += amount;
        
        cout << "Transferred $" << amount << " to account " << recipient.accountNumber << endl;
        cout << "Your new balance: $" << balance << endl;
    }
    
    void display() const {
        cout << "Account Number: " << accountNumber << endl;
        cout << "Account Holder: " << accountHolder << endl;
        cout << "Balance: $" << balance << endl;
    }
    
    string getAccountNumber() const { return accountNumber; }
};

class Bank {
private:
    vector<BankAccount> accounts;
    
public:
    void addAccount(const BankAccount& account) {
        accounts.push_back(account);
    }
    
    BankAccount& findAccount(const string& accountNumber) {
        for (auto& account : accounts) {
            if (account.getAccountNumber() == accountNumber) {
                return account;
            }
        }
        throw AccountNotFoundException(accountNumber);
    }
    
    void transfer(const string& fromAcc, const string& toAcc, double amount) {
        try {
            BankAccount& fromAccount = findAccount(fromAcc);
            BankAccount& toAccount = findAccount(toAcc);
            
            fromAccount.transferTo(toAccount, amount);
        }
        catch (const AccountNotFoundException& e) {
            cerr << e.what() << endl;
            throw; // Re-throw to let caller handle
        }
        catch (const exception& e) {
            cerr << "Transfer failed: " << e.what() << endl;
            throw; // Re-throw to let caller handle
        }
    }
};

int main() {
    Bank bank;
    
    // Create some bank accounts
    try {
        BankAccount account1("ACC001", "Alice Johnson", 1000.0);
        BankAccount account2("ACC002", "Bob Smith", 500.0);
        
        bank.addAccount(account1);
        bank.addAccount(account2);
        
        // Display accounts
        cout << "Initial Account States:" << endl;
        account1.display();
        cout << endl;
        account2.display();
        cout << endl;
        
        // Perform some transactions
        try {
            account1.deposit(250.0);
            account1.withdraw(200.0);
            
            // This will throw an exception
            account2.withdraw(600.0);
        }
        catch (const InsufficientFundsException& e) {
            cerr << e.what() << endl;
            cerr << "Attempted to withdraw $" << e.getAmount() 
                 << " but only $" << e.getBalance() << " available." << endl;
        }
        catch (const exception& e) {
            cerr << "Transaction error: " << e.what() << endl;
        }
        
        cout << endl;
        
        // Try a transfer
        try {
            bank.transfer("ACC001", "ACC002", 300.0);
        }
        catch (const exception& e) {
            cerr << "Transfer error: " << e.what() << endl;
        }
        
        // Try to find a non-existent account
        try {
            bank.findAccount("ACC999");
        }
        catch (const AccountNotFoundException& e) {
            cerr << e.what() << ": " << e.getAccountNumber() << endl;
        }
        
    }
    catch (const exception& e) {
        cerr << "Account creation error: " << e.what() << endl;
        return 1;
    }
    
    return 0;
}
Database Connection Manager

Exception handling manages database connection errors and resource cleanup.

// Database connection manager with exception handling and RAII
#include <iostream>
#include <stdexcept>
#include <string>
using namespace std;

// Custom exception classes for database errors
class DatabaseException : public exception {
private:
    string errorMessage;
    
public:
    DatabaseException(const string& message) : errorMessage(message) {}
    
    const char* what() const noexcept override {
        return errorMessage.c_str();
    }
};

class ConnectionFailedException : public DatabaseException {
public:
    ConnectionFailedException(const string& message) 
        : DatabaseException("Connection failed: " + message) {}
};

class QueryFailedException : public DatabaseException {
public:
    QueryFailedException(const string& message) 
        : DatabaseException("Query failed: " + message) {}
};

// Simulated database connection class
class DatabaseConnection {
private:
    string connectionString;
    bool isConnected;
    
    void simulateConnectionIssue() {
        // Simulate random connection issues (for demonstration)
        if (rand() % 5 == 0) {
            throw ConnectionFailedException("Network timeout");
        }
    }
    
    void simulateQueryIssue() {
        // Simulate random query issues (for demonstration)
        if (rand() % 7 == 0) {
            throw QueryFailedException("Syntax error");
        }
    }
    
public:
    DatabaseConnection(const string& connStr) 
        : connectionString(connStr), isConnected(false) {}
    
    ~DatabaseConnection() {
        if (isConnected) {
            disconnect();
        }
    }
    
    void connect() {
        if (isConnected) {
            return;
        }
        
        cout << "Connecting to database: " << connectionString << endl;
        
        try {
            simulateConnectionIssue();
            
            // Simulate connection process
            // In a real implementation, this would actually connect to a database
            isConnected = true;
            cout << "Connected successfully." << endl;
        }
        catch (const ConnectionFailedException& e) {
            cerr << e.what() << endl;
            throw; // Re-throw the exception
        }
        catch (const exception& e) {
            cerr << "Unexpected connection error: " << e.what() << endl;
            throw ConnectionFailedException(e.what());
        }
    }
    
    void disconnect() {
        if (!isConnected) {
            return;
        }
        
        cout << "Disconnecting from database..." << endl;
        isConnected = false;
        cout << "Disconnected." << endl;
    }
    
    void executeQuery(const string& query) {
        if (!isConnected) {
            throw DatabaseException("Not connected to database");
        }
        
        cout << "Executing query: " << query << endl;
        
        try {
            simulateQueryIssue();
            
            // Simulate query execution
            cout << "Query executed successfully." << endl;
        }
        catch (const QueryFailedException& e) {
            cerr << e.what() << endl;
            throw; // Re-throw the exception
        }
        catch (const exception& e) {
            cerr << "Unexpected query error: " << e.what() << endl;
            throw QueryFailedException(e.what());
        }
    }
    
    bool connected() const {
        return isConnected;
    }
};

class DatabaseManager {
public:
    static void performDatabaseOperations() {
        DatabaseConnection conn("server=localhost;database=mydb;user=admin");
        
        try {
            // Connect to database
            conn.connect();
            
            // Execute some queries
            conn.executeQuery("SELECT * FROM users");
            conn.executeQuery("UPDATE settings SET value = 'new' WHERE id = 1");
            conn.executeQuery("INSERT INTO logs (message) VALUES ('Operation completed')");
            
            // Disconnect (will happen automatically when conn goes out of scope)
            conn.disconnect();
        }
        catch (const ConnectionFailedException& e) {
            cerr << "Failed to establish database connection: " << e.what() << endl;
            // Attempt to reconnect or implement retry logic
            throw;
        }
        catch (const QueryFailedException& e) {
            cerr << "Database query failed: " << e.what() << endl;
            // Implement query retry or rollback logic
            throw;
        }
        catch (const exception& e) {
            cerr << "Unexpected database error: " << e.what() << endl;
            throw;
        }
    }
};

int main() {
    // Seed random number generator for simulation
    srand(time(nullptr));
    
    cout << "Database Operations Demo" << endl;
    cout << "=======================" << endl;
    
    try {
        DatabaseManager::performDatabaseOperations();
        cout << "All database operations completed successfully." << endl;
    }
    catch (const exception& e) {
        cerr << "Database operations failed: " << e.what() << endl;
        
        // In a real application, we might implement retry logic here
        cout << "Attempting to reconnect and retry..." << endl;
        
        // Simulate retry logic
        try {
            DatabaseManager::performDatabaseOperations();
            cout << "Retry successful. Database operations completed." << endl;
        }
        catch (const exception& e) {
            cerr << "Retry also failed: " << e.what() << endl;
            cerr << "Please check your database connection and try again later." << endl;
            return 1;
        }
    }
    
    return 0;
}