Real-World C++ Projects

Build practical applications to solidify your C++ knowledge

Simple Calculator

Build a console-based calculator that performs basic arithmetic operations.

Features:

  • Basic arithmetic operations (+, -, *, /)
  • Error handling for division by zero
  • Menu-driven interface
  • Input validation
calculator.cpp
#include <iostream>
#include <iomanip>
#include <limits>
using namespace std;

class Calculator {
private:
    double num1, num2;
    char operation;
    
public:
    void displayMenu() {
        cout << "\n========== CALCULATOR ==========" << endl;
        cout << "1. Addition (+)" << endl;
        cout << "2. Subtraction (-)" << endl;
        cout << "3. Multiplication (*)" << endl;
        cout << "4. Division (/)" << endl;
        cout << "5. Exit" << endl;
        cout << "===============================" << endl;
        cout << "Enter your choice (1-5): ";
    }
    
    bool getInput() {
        cout << "Enter first number: ";
        while (!(cin >> num1)) {
            cout << "Invalid input! Please enter a number: ";
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
        }
        
        cout << "Enter second number: ";
        while (!(cin >> num2)) {
            cout << "Invalid input! Please enter a number: ";
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
        }
        
        return true;
    }
    
    double add() {
        return num1 + num2;
    }
    
    double subtract() {
        return num1 - num2;
    }
    
    double multiply() {
        return num1 * num2;
    }
    
    double divide() {
        if (num2 == 0) {
            throw runtime_error("Division by zero is not allowed!");
        }
        return num1 / num2;
    }
    
    void displayResult(double result, char op) {
        cout << fixed << setprecision(2);
        cout << "\nResult: " << num1 << " " << op << " " << num2 << " = " << result << endl;
    }
    
    void run() {
        int choice;
        bool continueCalculating = true;
        
        cout << "Welcome to the C++ Calculator!" << endl;
        
        while (continueCalculating) {
            displayMenu();
            
            while (!(cin >> choice) || choice < 1 || choice > 5) {
                cout << "Invalid choice! Please enter a number between 1-5: ";
                cin.clear();
                cin.ignore(numeric_limits<streamsize>::max(), '\n');
            }
            
            if (choice == 5) {
                cout << "Thank you for using the calculator!" << endl;
                continueCalculating = false;
                continue;
            }
            
            if (!getInput()) {
                continue;
            }
            
            try {
                double result;
                char op;
                
                switch (choice) {
                    case 1:
                        result = add();
                        op = '+';
                        break;
                    case 2:
                        result = subtract();
                        op = '-';
                        break;
                    case 3:
                        result = multiply();
                        op = '*';
                        break;
                    case 4:
                        result = divide();
                        op = '/';
                        break;
                }
                
                displayResult(result, op);
                
            } catch (const exception& e) {
                cout << "Error: " << e.what() << endl;
            }
            
            cout << "\nPress Enter to continue...";
            cin.ignore();
            cin.get();
        }
    }
};

int main() {
    Calculator calc;
    calc.run();
    return 0;
}

Banking System

Create a comprehensive banking system with account management and transactions.

Features:

  • Account creation and management
  • Deposit and withdrawal operations
  • Balance inquiry
  • Transaction history
  • File I/O for data persistence
banking_system.cpp
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <iomanip>
#include <algorithm>
#include <ctime>
using namespace std;

class Transaction {
public:
    string type;
    double amount;
    string date;
    double balanceAfter;
    
    Transaction(string t, double a, double balance) : type(t), amount(a), balanceAfter(balance) {
        time_t now = time(0);
        date = ctime(&now);
        date.pop_back(); // Remove newline
    }
};

class BankAccount {
private:
    string accountNumber;
    string accountHolder;
    double balance;
    vector<Transaction> transactions;
    
public:
    BankAccount() : balance(0.0) {}
    
    BankAccount(string accNum, string holder, double initialBalance = 0.0) 
        : accountNumber(accNum), accountHolder(holder), balance(initialBalance) {
        if (initialBalance > 0) {
            transactions.push_back(Transaction("Initial Deposit", initialBalance, balance));
        }
    }
    
    // Getters
    string getAccountNumber() const { return accountNumber; }
    string getAccountHolder() const { return accountHolder; }
    double getBalance() const { return balance; }
    
    bool deposit(double amount) {
        if (amount <= 0) {
            cout << "Invalid amount! Deposit amount must be positive." << endl;
            return false;
        }
        
        balance += amount;
        transactions.push_back(Transaction("Deposit", amount, balance));
        cout << "Successfully deposited $" << fixed << setprecision(2) << amount << endl;
        cout << "New balance: $" << balance << endl;
        return true;
    }
    
    bool withdraw(double amount) {
        if (amount <= 0) {
            cout << "Invalid amount! Withdrawal amount must be positive." << endl;
            return false;
        }
        
        if (amount > balance) {
            cout << "Insufficient funds! Current balance: $" << fixed << setprecision(2) << balance << endl;
            return false;
        }
        
        balance -= amount;
        transactions.push_back(Transaction("Withdrawal", amount, balance));
        cout << "Successfully withdrew $" << fixed << setprecision(2) << amount << endl;
        cout << "New balance: $" << balance << endl;
        return true;
    }
    
    void displayAccountInfo() const {
        cout << "\n========== ACCOUNT INFORMATION ==========" << endl;
        cout << "Account Number: " << accountNumber << endl;
        cout << "Account Holder: " << accountHolder << endl;
        cout << "Current Balance: $" << fixed << setprecision(2) << balance << endl;
        cout << "=========================================" << endl;
    }
    
    void displayTransactionHistory() const {
        cout << "\n========== TRANSACTION HISTORY ==========" << endl;
        if (transactions.empty()) {
            cout << "No transactions found." << endl;
            return;
        }
        
        cout << left << setw(15) << "Type" << setw(12) << "Amount" 
             << setw(12) << "Balance" << "Date" << endl;
        cout << string(60, '-') << endl;
        
        for (const auto& transaction : transactions) {
            cout << left << setw(15) << transaction.type 
                 << "$" << setw(11) << fixed << setprecision(2) << transaction.amount
                 << "$" << setw(11) << transaction.balanceAfter
                 << transaction.date << endl;
        }
        cout << "=========================================" << endl;
    }
    
    // File I/O methods
    void saveToFile() const {
        ofstream file(accountNumber + ".txt");
        if (file.is_open()) {
            file << accountNumber << endl;
            file << accountHolder << endl;
            file << balance << endl;
            file << transactions.size() << endl;
            
            for (const auto& transaction : transactions) {
                file << transaction.type << "|" << transaction.amount << "|" 
                     << transaction.balanceAfter << "|" << transaction.date << endl;
            }
            file.close();
        }
    }
    
    bool loadFromFile(const string& accNum) {
        ifstream file(accNum + ".txt");
        if (!file.is_open()) {
            return false;
        }
        
        string line;
        getline(file, accountNumber);
        getline(file, accountHolder);
        file >> balance;
        
        int transactionCount;
        file >> transactionCount;
        file.ignore(); // Ignore newline
        
        transactions.clear();
        for (int i = 0; i < transactionCount; i++) {
            getline(file, line);
            // Parse transaction data (simplified)
            size_t pos1 = line.find('|');
            size_t pos2 = line.find('|', pos1 + 1);
            size_t pos3 = line.find('|', pos2 + 1);
            
            if (pos1 != string::npos && pos2 != string::npos && pos3 != string::npos) {
                string type = line.substr(0, pos1);
                double amount = stod(line.substr(pos1 + 1, pos2 - pos1 - 1));
                double balanceAfter = stod(line.substr(pos2 + 1, pos3 - pos2 - 1));
                
                Transaction trans(type, amount, balanceAfter);
                trans.date = line.substr(pos3 + 1);
                transactions.push_back(trans);
            }
        }
        
        file.close();
        return true;
    }
};

class BankingSystem {
private:
    vector<BankAccount> accounts;
    
public:
    void displayMainMenu() {
        cout << "\n========== BANKING SYSTEM ==========" << endl;
        cout << "1. Create New Account" << endl;
        cout << "2. Login to Existing Account" << endl;
        cout << "3. Exit" << endl;
        cout << "====================================" << endl;
        cout << "Enter your choice: ";
    }
    
    void displayAccountMenu() {
        cout << "\n========== ACCOUNT MENU ==========" << endl;
        cout << "1. Check Balance" << endl;
        cout << "2. Deposit Money" << endl;
        cout << "3. Withdraw Money" << endl;
        cout << "4. Transaction History" << endl;
        cout << "5. Logout" << endl;
        cout << "==================================" << endl;
        cout << "Enter your choice: ";
    }
    
    void createAccount() {
        string accountNumber, accountHolder;
        double initialDeposit;
        
        cout << "\n========== CREATE NEW ACCOUNT ==========" << endl;
        cout << "Enter account number: ";
        cin >> accountNumber;
        cin.ignore();
        
        cout << "Enter account holder name: ";
        getline(cin, accountHolder);
        
        cout << "Enter initial deposit amount: $";
        cin >> initialDeposit;
        
        BankAccount newAccount(accountNumber, accountHolder, initialDeposit);
        newAccount.saveToFile();
        
        cout << "Account created successfully!" << endl;
        cout << "Account Number: " << accountNumber << endl;
        cout << "Account Holder: " << accountHolder << endl;
        cout << "Initial Balance: $" << fixed << setprecision(2) << initialDeposit << endl;
    }
    
    void loginAccount() {
        string accountNumber;
        cout << "\nEnter account number: ";
        cin >> accountNumber;
        
        BankAccount account;
        if (!account.loadFromFile(accountNumber)) {
            cout << "Account not found!" << endl;
            return;
        }
        
        cout << "Login successful!" << endl;
        account.displayAccountInfo();
        
        int choice;
        bool loggedIn = true;
        
        while (loggedIn) {
            displayAccountMenu();
            cin >> choice;
            
            switch (choice) {
                case 1:
                    account.displayAccountInfo();
                    break;
                case 2: {
                    double amount;
                    cout << "Enter deposit amount: $";
                    cin >> amount;
                    account.deposit(amount);
                    account.saveToFile();
                    break;
                }
                case 3: {
                    double amount;
                    cout << "Enter withdrawal amount: $";
                    cin >> amount;
                    account.withdraw(amount);
                    account.saveToFile();
                    break;
                }
                case 4:
                    account.displayTransactionHistory();
                    break;
                case 5:
                    cout << "Logged out successfully!" << endl;
                    loggedIn = false;
                    break;
                default:
                    cout << "Invalid choice! Please try again." << endl;
            }
            
            if (loggedIn && choice != 5) {
                cout << "\nPress Enter to continue...";
                cin.ignore();
                cin.get();
            }
        }
    }
    
    void run() {
        cout << "Welcome to the Banking System!" << endl;
        
        int choice;
        bool running = true;
        
        while (running) {
            displayMainMenu();
            cin >> choice;
            
            switch (choice) {
                case 1:
                    createAccount();
                    break;
                case 2:
                    loginAccount();
                    break;
                case 3:
                    cout << "Thank you for using our Banking System!" << endl;
                    running = false;
                    break;
                default:
                    cout << "Invalid choice! Please try again." << endl;
            }
            
            if (running && choice != 3) {
                cout << "\nPress Enter to continue...";
                cin.ignore();
                cin.get();
            }
        }
    }
};

int main() {
    BankingSystem bank;
    bank.run();
    return 0;
}

Student Management System

Build a comprehensive student management system with grade tracking and reporting.

Features:

  • Student registration and management
  • Grade entry and calculation
  • GPA calculation
  • Student search and filtering
  • Report generation
student_management.cpp
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <iomanip>
#include <fstream>
using namespace std;

class Grade {
public:
    string subject;
    double score;
    int credits;
    
    Grade(string subj, double sc, int cr) : subject(subj), score(sc), credits(cr) {}
    
    char getLetterGrade() const {
        if (score >= 90) return 'A';
        else if (score >= 80) return 'B';
        else if (score >= 70) return 'C';
        else if (score >= 60) return 'D';
        else return 'F';
    }
    
    double getGradePoints() const {
        char letter = getLetterGrade();
        switch (letter) {
            case 'A': return 4.0;
            case 'B': return 3.0;
            case 'C': return 2.0;
            case 'D': return 1.0;
            default: return 0.0;
        }
    }
};

class Student {
private:
    string studentId;
    string firstName;
    string lastName;
    string email;
    string phoneNumber;
    vector<Grade> grades;
    
public:
    Student() {}
    
    Student(string id, string fName, string lName, string mail, string phone)
        : studentId(id), firstName(fName), lastName(lName), email(mail), phoneNumber(phone) {}
    
    // Getters
    string getStudentId() const { return studentId; }
    string getFirstName() const { return firstName; }
    string getLastName() const { return lastName; }
    string getFullName() const { return firstName + " " + lastName; }
    string getEmail() const { return email; }
    string getPhoneNumber() const { return phoneNumber; }
    
    // Setters
    void setEmail(string mail) { email = mail; }
    void setPhoneNumber(string phone) { phoneNumber = phone; }
    
    void addGrade(const Grade& grade) {
        grades.push_back(grade);
    }
    
    void removeGrade(const string& subject) {
        grades.erase(remove_if(grades.begin(), grades.end(),
                               [&subject](const Grade& g) { return g.subject == subject; }),
                    grades.end());
    }
    
    double calculateGPA() const {
        if (grades.empty()) return 0.0;
        
        double totalPoints = 0.0;
        int totalCredits = 0;
        
        for (const auto& grade : grades) {
            totalPoints += grade.getGradePoints() * grade.credits;
            totalCredits += grade.credits;
        }
        
        return totalCredits > 0 ? totalPoints / totalCredits : 0.0;
    }
    
    double calculateAverageScore() const {
        if (grades.empty()) return 0.0;
        
        double total = 0.0;
        for (const auto& grade : grades) {
            total += grade.score;
        }
        return total / grades.size();
    }
    
    void displayStudentInfo() const {
        cout << "\n========== STUDENT INFORMATION ==========" << endl;
        cout << "Student ID: " << studentId << endl;
        cout << "Name: " << getFullName() << endl;
        cout << "Email: " << email << endl;
        cout << "Phone: " << phoneNumber << endl;
        cout << "GPA: " << fixed << setprecision(2) << calculateGPA() << endl;
        cout << "Average Score: " << fixed << setprecision(2) << calculateAverageScore() << "%" << endl;
        cout << "=========================================" << endl;
    }
    
    void displayGrades() const {
        cout << "\n========== GRADES ==========" << endl;
        if (grades.empty()) {
            cout << "No grades recorded." << endl;
            return;
        }
        
        cout << left << setw(20) << "Subject" << setw(8) << "Score" 
             << setw(8) << "Grade" << setw(10) << "Credits" << "Points" << endl;
        cout << string(55, '-') << endl;
        
        for (const auto& grade : grades) {
            cout << left << setw(20) << grade.subject
                 << setw(8) << fixed << setprecision(1) << grade.score
                 << setw(8) << grade.getLetterGrade()
                 << setw(10) << grade.credits
                 << fixed << setprecision(1) << grade.getGradePoints() << endl;
        }
        
        cout << string(55, '-') << endl;
        cout << "GPA: " << fixed << setprecision(2) << calculateGPA() << endl;
        cout << "============================" << endl;
    }
    
    bool hasGrade(const string& subject) const {
        return find_if(grades.begin(), grades.end(),
                      [&subject](const Grade& g) { return g.subject == subject; }) != grades.end();
    }
    
    // File I/O
    void saveToFile(ofstream& file) const {
        file << studentId << "|" << firstName << "|" << lastName << "|" 
             << email << "|" << phoneNumber << "|" << grades.size() << endl;
        
        for (const auto& grade : grades) {
            file << grade.subject << "|" << grade.score << "|" << grade.credits << endl;
        }
    }
    
    void loadFromFile(ifstream& file) {
        string line;
        getline(file, line);
        
        size_t pos = 0;
        vector<string> tokens;
        string token;
        
        while ((pos = line.find('|')) != string::npos) {
            token = line.substr(0, pos);
            tokens.push_back(token);
            line.erase(0, pos + 1);
        }
        tokens.push_back(line); // Last token
        
        if (tokens.size() >= 6) {
            studentId = tokens[0];
            firstName = tokens[1];
            lastName = tokens[2];
            email = tokens[3];
            phoneNumber = tokens[4];
            int gradeCount = stoi(tokens[5]);
            
            grades.clear();
            for (int i = 0; i < gradeCount; i++) {
                getline(file, line);
                pos = 0;
                tokens.clear();
                
                while ((pos = line.find('|')) != string::npos) {
                    token = line.substr(0, pos);
                    tokens.push_back(token);
                    line.erase(0, pos + 1);
                }
                tokens.push_back(line);
                
                if (tokens.size() >= 3) {
                    grades.emplace_back(tokens[0], stod(tokens[1]), stoi(tokens[2]));
                }
            }
        }
    }
};

class StudentManagementSystem {
private:
    vector<Student> students;
    const string filename = "students.txt";
    
public:
    StudentManagementSystem() {
        loadFromFile();
    }
    
    ~StudentManagementSystem() {
        saveToFile();
    }
    
    void displayMainMenu() {
        cout << "\n========== STUDENT MANAGEMENT SYSTEM ==========" << endl;
        cout << "1. Add New Student" << endl;
        cout << "2. Search Student" << endl;
        cout << "3. Display All Students" << endl;
        cout << "4. Add Grade to Student" << endl;
        cout << "5. Display Student Grades" << endl;
        cout << "6. Generate Class Report" << endl;
        cout << "7. Remove Student" << endl;
        cout << "8. Exit" << endl;
        cout << "===============================================" << endl;
        cout << "Enter your choice: ";
    }
    
    void addStudent() {
        string id, firstName, lastName, email, phone;
        
        cout << "\n========== ADD NEW STUDENT ==========" << endl;
        cout << "Enter Student ID: ";
        cin >> id;
        
        // Check if student already exists
        if (findStudent(id) != nullptr) {
            cout << "Student with ID " << id << " already exists!" << endl;
            return;
        }
        
        cin.ignore();
        cout << "Enter First Name: ";
        getline(cin, firstName);
        cout << "Enter Last Name: ";
        getline(cin, lastName);
        cout << "Enter Email: ";
        getline(cin, email);
        cout << "Enter Phone Number: ";
        getline(cin, phone);
        
        students.emplace_back(id, firstName, lastName, email, phone);
        cout << "Student added successfully!" << endl;
    }
    
    Student* findStudent(const string& id) {
        auto it = find_if(students.begin(), students.end(),
                         [&id](const Student& s) { return s.getStudentId() == id; });
        return it != students.end() ? &(*it) : nullptr;
    }
    
    void searchStudent() {
        string id;
        cout << "\nEnter Student ID to search: ";
        cin >> id;
        
        Student* student = findStudent(id);
        if (student) {
            student->displayStudentInfo();
        } else {
            cout << "Student not found!" << endl;
        }
    }
    
    void displayAllStudents() {
        cout << "\n========== ALL STUDENTS ==========" << endl;
        if (students.empty()) {
            cout << "No students registered." << endl;
            return;
        }
        
        cout << left << setw(12) << "ID" << setw(25) << "Name" 
             << setw(8) << "GPA" << "Email" << endl;
        cout << string(70, '-') << endl;
        
        for (const auto& student : students) {
            cout << left << setw(12) << student.getStudentId()
                 << setw(25) << student.getFullName()
                 << setw(8) << fixed << setprecision(2) << student.calculateGPA()
                 << student.getEmail() << endl;
        }
        cout << "==================================" << endl;
    }
    
    void addGrade() {
        string id, subject;
        double score;
        int credits;
        
        cout << "\nEnter Student ID: ";
        cin >> id;
        
        Student* student = findStudent(id);
        if (!student) {
            cout << "Student not found!" << endl;
            return;
        }
        
        cin.ignore();
        cout << "Enter Subject: ";
        getline(cin, subject);
        
        if (student->hasGrade(subject)) {
            cout << "Grade for " << subject << " already exists!" << endl;
            return;
        }
        
        cout << "Enter Score (0-100): ";
        cin >> score;
        cout << "Enter Credits: ";
        cin >> credits;
        
        if (score < 0 || score > 100) {
            cout << "Invalid score! Score must be between 0 and 100." << endl;
            return;
        }
        
        student->addGrade(Grade(subject, score, credits));
        cout << "Grade added successfully!" << endl;
    }
    
    void displayStudentGrades() {
        string id;
        cout << "\nEnter Student ID: ";
        cin >> id;
        
        Student* student = findStudent(id);
        if (student) {
            student->displayStudentInfo();
            student->displayGrades();
        } else {
            cout << "Student not found!" << endl;
        }
    }
    
    void generateClassReport() {
        cout << "\n========== CLASS REPORT ==========" << endl;
        if (students.empty()) {
            cout << "No students registered." << endl;
            return;
        }
        
        double totalGPA = 0.0;
        double highestGPA = 0.0;
        double lowestGPA = 4.0;
        string topStudent, bottomStudent;
        
        for (const auto& student : students) {
            double gpa = student.calculateGPA();
            totalGPA += gpa;
            
            if (gpa > highestGPA) {
                highestGPA = gpa;
                topStudent = student.getFullName();
            }
            
            if (gpa < lowestGPA) {
                lowestGPA = gpa;
                bottomStudent = student.getFullName();
            }
        }
        
        cout << "Total Students: " << students.size() << endl;
        cout << "Average Class GPA: " << fixed << setprecision(2) << totalGPA / students.size() << endl;
        cout << "Highest GPA: " << highestGPA << " (" << topStudent << ")" << endl;
        cout << "Lowest GPA: " << lowestGPA << " (" << bottomStudent << ")" << endl;
        cout << "==================================" << endl;
    }
    
    void removeStudent() {
        string id;
        cout << "\nEnter Student ID to remove: ";
        cin >> id;
        
        auto it = find_if(students.begin(), students.end(),
                         [&id](const Student& s) { return s.getStudentId() == id; });
        
        if (it != students.end()) {
            cout << "Removing student: " << it->getFullName() << endl;
            students.erase(it);
            cout << "Student removed successfully!" << endl;
        } else {
            cout << "Student not found!" << endl;
        }
    }
    
    void saveToFile() {
        ofstream file(filename);
        if (file.is_open()) {
            file << students.size() << endl;
            for (const auto& student : students) {
                student.saveToFile(file);
            }
            file.close();
        }
    }
    
    void loadFromFile() {
        ifstream file(filename);
        if (file.is_open()) {
            int studentCount;
            file >> studentCount;
            file.ignore();
            
            students.clear();
            for (int i = 0; i < studentCount; i++) {
                Student student;
                student.loadFromFile(file);
                students.push_back(student);
            }
            file.close();
        }
    }
    
    void run() {
        cout << "Welcome to Student Management System!" << endl;
        
        int choice;
        bool running = true;
        
        while (running) {
            displayMainMenu();
            cin >> choice;
            
            switch (choice) {
                case 1: addStudent(); break;
                case 2: searchStudent(); break;
                case 3: displayAllStudents(); break;
                case 4: addGrade(); break;
                case 5: displayStudentGrades(); break;
                case 6: generateClassReport(); break;
                case 7: removeStudent(); break;
                case 8:
                    cout << "Thank you for using Student Management System!" << endl;
                    running = false;
                    break;
                default:
                    cout << "Invalid choice! Please try again." << endl;
            }
            
            if (running && choice != 8) {
                cout << "\nPress Enter to continue...";
                cin.ignore();
                cin.get();
            }
        }
    }
};

int main() {
    StudentManagementSystem sms;
    sms.run();
    return 0;
}

Tic-Tac-Toe Game

Create an interactive Tic-Tac-Toe game with AI opponent and game statistics.

Features:

  • Two-player mode
  • AI opponent with different difficulty levels
  • Game statistics tracking
  • Input validation
  • Colorful console output
tic_tac_toe.cpp
#include <iostream>
#include <vector>
#include <random>
#include <algorithm>
#include <limits>
using namespace std;

class TicTacToe {
private:
    vector<vector<char>> board;
    char currentPlayer;
    bool gameOver;
    char winner;
    int playerXWins;
    int playerOWins;
    int draws;
    bool vsAI;
    int aiDifficulty; // 1: Easy, 2: Medium, 3: Hard
    
public:
    TicTacToe() : board(3, vector<char>(3, ' ')), currentPlayer('X'), 
                  gameOver(false), winner(' '), playerXWins(0), 
                  playerOWins(0), draws(0), vsAI(false), aiDifficulty(1) {}
    
    void displayBoard() {
        cout << "\n   |   |   " << endl;
        cout << " " << board[0][0] << " | " << board[0][1] << " | " << board[0][2] << endl;
        cout << "___|___|___" << endl;
        cout << "   |   |   " << endl;
        cout << " " << board[1][0] << " | " << board[1][1] << " | " << board[1][2] << endl;
        cout << "___|___|___" << endl;
        cout << "   |   |   " << endl;
        cout << " " << board[2][0] << " | " << board[2][1] << " | " << board[2][2] << endl;
        cout << "   |   |   " << endl;
        
        cout << "\nPositions:" << endl;
        cout << " 1 | 2 | 3 " << endl;
        cout << "___|___|___" << endl;
        cout << " 4 | 5 | 6 " << endl;
        cout << "___|___|___" << endl;
        cout << " 7 | 8 | 9 " << endl;
    }
    
    bool isValidMove(int position) {
        if (position < 1 || position > 9) return false;
        
        int row = (position - 1) / 3;
        int col = (position - 1) % 3;
        
        return board[row][col] == ' ';
    }
    
    void makeMove(int position) {
        int row = (position - 1) / 3;
        int col = (position - 1) % 3;
        board[row][col] = currentPlayer;
    }
    
    bool checkWinner() {
        // Check rows
        for (int i = 0; i < 3; i++) {
            if (board[i][0] != ' ' && board[i][0] == board[i][1] && board[i][1] == board[i][2]) {
                winner = board[i][0];
                return true;
            }
        }
        
        // Check columns
        for (int j = 0; j < 3; j++) {
            if (board[0][j] != ' ' && board[0][j] == board[1][j] && board[1][j] == board[2][j]) {
                winner = board[0][j];
                return true;
            }
        }
        
        // Check diagonals
        if (board[0][0] != ' ' && board[0][0] == board[1][1] && board[1][1] == board[2][2]) {
            winner = board[0][0];
            return true;
        }
        
        if (board[0][2] != ' ' && board[0][2] == board[1][1] && board[1][1] == board[2][0]) {
            winner = board[0][2];
            return true;
        }
        
        return false;
    }
    
    bool isBoardFull() {
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (board[i][j] == ' ') return false;
            }
        }
        return true;
    }
    
    vector<int> getAvailableMoves() {
        vector<int> moves;
        for (int i = 1; i <= 9; i++) {
            if (isValidMove(i)) {
                moves.push_back(i);
            }
        }
        return moves;
    }
    
    int minimax(vector<vector<char>> tempBoard, bool isMaximizing, char aiPlayer, char humanPlayer) {
        // Check for terminal states
        char tempWinner = checkWinnerForBoard(tempBoard);
        if (tempWinner == aiPlayer) return 1;
        if (tempWinner == humanPlayer) return -1;
        if (isBoardFullForBoard(tempBoard)) return 0;
        
        if (isMaximizing) {
            int bestScore = -1000;
            for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 3; j++) {
                    if (tempBoard[i][j] == ' ') {
                        tempBoard[i][j] = aiPlayer;
                        int score = minimax(tempBoard, false, aiPlayer, humanPlayer);
                        tempBoard[i][j] = ' ';
                        bestScore = max(score, bestScore);
                    }
                }
            }
            return bestScore;
        } else {
            int bestScore = 1000;
            for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 3; j++) {
                    if (tempBoard[i][j] == ' ') {
                        tempBoard[i][j] = humanPlayer;
                        int score = minimax(tempBoard, true, aiPlayer, humanPlayer);
                        tempBoard[i][j] = ' ';
                        bestScore = min(score, bestScore);
                    }
                }
            }
            return bestScore;
        }
    }
    
    char checkWinnerForBoard(const vector<vector<char>>& tempBoard) {
        // Check rows
        for (int i = 0; i < 3; i++) {
            if (tempBoard[i][0] != ' ' && tempBoard[i][0] == tempBoard[i][1] && tempBoard[i][1] == tempBoard[i][2]) {
                return tempBoard[i][0];
            }
        }
        
        // Check columns
        for (int j = 0; j < 3; j++) {
            if (tempBoard[0][j] != ' ' && tempBoard[0][j] == tempBoard[1][j] && tempBoard[1][j] == tempBoard[2][j]) {
                return tempBoard[0][j];
            }
        }
        
        // Check diagonals
        if (tempBoard[0][0] != ' ' && tempBoard[0][0] == tempBoard[1][1] && tempBoard[1][1] == tempBoard[2][2]) {
            return tempBoard[0][0];
        }
        
        if (tempBoard[0][2] != ' ' && tempBoard[0][2] == tempBoard[1][1] && tempBoard[1][1] == tempBoard[2][0]) {
            return tempBoard[0][2];
        }
        
        return ' ';
    }
    
    bool isBoardFullForBoard(const vector<vector<char>>& tempBoard) {
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (tempBoard[i][j] == ' ') return false;
            }
        }
        return true;
    }
    
    int getAIMove() {
        vector<int> availableMoves = getAvailableMoves();
        
        if (aiDifficulty == 1) { // Easy - Random move
            random_device rd;
            mt19937 gen(rd());
            uniform_int_distribution<int> dis(0, availableMoves.size() - 1);
            return availableMoves[dis(gen)];
        }
        else if (aiDifficulty == 2) { // Medium - 70% optimal, 30% random
            random_device rd;
            mt19937 gen(rd());
            uniform_int_distribution<int> dis(1, 10);
            
            if (dis(gen) <= 7) {
                // Make optimal move
                return getBestMove();
            } else {
                // Make random move
                uniform_int_distribution<int> randomDis(0, availableMoves.size() - 1);
                return availableMoves[randomDis(gen)];
            }
        }
        else { // Hard - Always optimal
            return getBestMove();
        }
    }
    
    int getBestMove() {
        int bestScore = -1000;
        int bestMove = -1;
        char aiPlayer = currentPlayer;
        char humanPlayer = (aiPlayer == 'X') ? 'O' : 'X';
        
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (board[i][j] == ' ') {
                    board[i][j] = aiPlayer;
                    int score = minimax(board, false, aiPlayer, humanPlayer);
                    board[i][j] = ' ';
                    
                    if (score > bestScore) {
                        bestScore = score;
                        bestMove = i * 3 + j + 1;
                    }
                }
            }
        }
        
        return bestMove;
    }
    
    void switchPlayer() {
        currentPlayer = (currentPlayer == 'X') ? 'O' : 'X';
    }
    
    void resetGame() {
        board = vector<vector<char>>(3, vector<char>(3, ' '));
        currentPlayer = 'X';
        gameOver = false;
        winner = ' ';
    }
    
    void displayStats() {
        cout << "\n========== GAME STATISTICS ==========" << endl;
        cout << "Player X Wins: " << playerXWins << endl;
        cout << "Player O Wins: " << playerOWins << endl;
        cout << "Draws: " << draws << endl;
        cout << "Total Games: " << (playerXWins + playerOWins + draws) << endl;
        cout << "=====================================" << endl;
    }
    
    void displayMainMenu() {
        cout << "\n========== TIC-TAC-TOE GAME ==========" << endl;
        cout << "1. Play vs Human" << endl;
        cout << "2. Play vs AI" << endl;
        cout << "3. View Statistics" << endl;
        cout << "4. Reset Statistics" << endl;
        cout << "5. Exit" << endl;
        cout << "=====================================" << endl;
        cout << "Enter your choice: ";
    }
    
    void selectAIDifficulty() {
        cout << "\nSelect AI Difficulty:" << endl;
        cout << "1. Easy (Random moves)" << endl;
        cout << "2. Medium (Mixed strategy)" << endl;
        cout << "3. Hard (Unbeatable)" << endl;
        cout << "Enter difficulty (1-3): ";
        
        while (!(cin >> aiDifficulty) || aiDifficulty < 1 || aiDifficulty > 3) {
            cout << "Invalid input! Please enter 1, 2, or 3: ";
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
        }
    }
    
    void playGame() {
        resetGame();
        
        cout << "\nStarting new game!" << endl;
        if (vsAI) {
            string difficulty[] = {"", "Easy", "Medium", "Hard"};
            cout << "Playing against AI (" << difficulty[aiDifficulty] << " difficulty)" << endl;
            cout << "You are X, AI is O" << endl;
        } else {
            cout << "Two-player mode" << endl;
        }
        
        while (!gameOver) {
            displayBoard();
            cout << "\nCurrent player: " << currentPlayer << endl;
            
            int position;
            
            if (vsAI && currentPlayer == 'O') {
                cout << "AI is thinking..." << endl;
                position = getAIMove();
                cout << "AI chooses position " << position << endl;
            } else {
                cout << "Enter position (1-9): ";
                while (!(cin >> position) || !isValidMove(position)) {
                    if (cin.fail()) {
                        cout << "Invalid input! Please enter a number: ";
                        cin.clear();
                        cin.ignore(numeric_limits<streamsize>::max(), '\n');
                    } else {
                        cout << "Invalid move! Position already taken or out of range. Try again: ";
                    }
                }
            }
            
            makeMove(position);
            
            if (checkWinner()) {
                displayBoard();
                cout << "\nšŸŽ‰ Player " << winner << " wins! šŸŽ‰" << endl;
                if (winner == 'X') playerXWins++;
                else playerOWins++;
                gameOver = true;
            } else if (isBoardFull()) {
                displayBoard();
                cout << "\nšŸ¤ It's a draw! šŸ¤" << endl;
                draws++;
                gameOver = true;
            } else {
                switchPlayer();
            }
        }
    }
    
    void run() {
        cout << "Welcome to Tic-Tac-Toe!" << endl;
        
        int choice;
        bool running = true;
        
        while (running) {
            displayMainMenu();
            
            while (!(cin >> choice) || choice < 1 || choice > 5) {
                cout << "Invalid choice! Please enter a number between 1-5: ";
                cin.clear();
                cin.ignore(numeric_limits<streamsize>::max(), '\n');
            }
            
            switch (choice) {
                case 1:
                    vsAI = false;
                    playGame();
                    break;
                case 2:
                    vsAI = true;
                    selectAIDifficulty();
                    playGame();
                    break;
                case 3:
                    displayStats();
                    break;
                case 4:
                    playerXWins = playerOWins = draws = 0;
                    cout << "Statistics reset!" << endl;
                    break;
                case 5:
                    cout << "Thanks for playing Tic-Tac-Toe!" << endl;
                    running = false;
                    break;
            }
            
            if (running && choice != 5) {
                cout << "\nPress Enter to continue...";
                cin.ignore();
                cin.get();
            }
        }
    }
};

int main() {
    TicTacToe game;
    game.run();
    return 0;
}

Library Management System

Build a comprehensive library management system with book tracking and member management.

Features:

  • Book inventory management
  • Member registration and management
  • Book borrowing and returning
  • Search and filter functionality
  • Due date tracking and fines
  • Reports and statistics
library_management.cpp
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <fstream>
#include <ctime>
#include <iomanip>
using namespace std;

class Book {
public:
    string isbn;
    string title;
    string author;
    string genre;
    bool isAvailable;
    string borrowedBy;
    string borrowDate;
    string dueDate;
    
    Book() : isAvailable(true) {}
    
    Book(string is, string t, string a, string g) 
        : isbn(is), title(t), author(a), genre(g), isAvailable(true) {}
    
    void displayBook() const {
        cout << left << setw(15) << isbn 
             << setw(30) << title 
             << setw(20) << author 
             << setw(15) << genre 
             << (isAvailable ? "Available" : "Borrowed") << endl;
    }
    
    void borrowBook(const string& memberId) {
        isAvailable = false;
        borrowedBy = memberId;
        
        time_t now = time(0);
        borrowDate = ctime(&now);
        borrowDate.pop_back(); // Remove newline
        
        // Set due date (14 days from now)
        time_t dueTime = now + (14 * 24 * 60 * 60);
        dueDate = ctime(&dueTime);
        dueDate.pop_back();
    }
    
    void returnBook() {
        isAvailable = true;
        borrowedBy = "";
        borrowDate = "";
        dueDate = "";
    }
};

class Member {
public:
    string memberId;
    string name;
    string email;
    string phone;
    vector<string> borrowedBooks;
    double fineAmount;
    
    Member() : fineAmount(0.0) {}
    
    Member(string id, string n, string e, string p)
        : memberId(id), name(n), email(e), phone(p), fineAmount(0.0) {}
    
    void displayMember() const {
        cout << left << setw(12) << memberId 
             << setw(25) << name 
             << setw(30) << email 
             << setw(15) << phone 
             << borrowedBooks.size() << " books, $" 
             << fixed << setprecision(2) << fineAmount << " fine" << endl;
    }
    
    void addBorrowedBook(const string& isbn) {
        borrowedBooks.push_back(isbn);
    }
    
    void removeBorrowedBook(const string& isbn) {
        borrowedBooks.erase(remove(borrowedBooks.begin(), borrowedBooks.end(), isbn),
                           borrowedBooks.end());
    }
    
    void addFine(double amount) {
        fineAmount += amount;
    }
    
    void payFine(double amount) {
        fineAmount = max(0.0, fineAmount - amount);
    }
};

class LibraryManagementSystem {
private:
    vector<Book> books;
    vector<Member> members;
    const string booksFile = "books.txt";
    const string membersFile = "members.txt";
    
public:
    LibraryManagementSystem() {
        loadData();
    }
    
    ~LibraryManagementSystem() {
        saveData();
    }
    
    void displayMainMenu() {
        cout << "\n========== LIBRARY MANAGEMENT SYSTEM ==========" << endl;
        cout << "1. Book Management" << endl;
        cout << "2. Member Management" << endl;
        cout << "3. Borrow Book" << endl;
        cout << "4. Return Book" << endl;
        cout << "5. Search Books" << endl;
        cout << "6. View Reports" << endl;
        cout << "7. Manage Fines" << endl;
        cout << "8. Exit" << endl;
        cout << "===============================================" << endl;
        cout << "Enter your choice: ";
    }
    
    void addBook() {
        string isbn, title, author, genre;
        
        cout << "\n========== ADD NEW BOOK ==========" << endl;
        cout << "Enter ISBN: ";
        cin >> isbn;
        
        if (findBook(isbn) != nullptr) {
            cout << "Book with ISBN " << isbn << " already exists!" << endl;
            return;
        }
        
        cin.ignore();
        cout << "Enter Title: ";
        getline(cin, title);
        cout << "Enter Author: ";
        getline(cin, author);
        cout << "Enter Genre: ";
        getline(cin, genre);
        
        books.emplace_back(isbn, title, author, genre);
        cout << "Book added successfully!" << endl;
    }
    
    void displayAllBooks() {
        cout << "\n========== ALL BOOKS ==========" << endl;
        if (books.empty()) {
            cout << "No books in the library." << endl;
            return;
        }
        
        cout << left << setw(15) << "ISBN" 
             << setw(30) << "Title" 
             << setw(20) << "Author" 
             << setw(15) << "Genre" 
             << "Status" << endl;
        cout << string(90, '-') << endl;
        
        for (const auto& book : books) {
            book.displayBook();
        }
        cout << "===============================" << endl;
    }
    
    void addMember() {
        string id, name, email, phone;
        
        cout << "\n========== ADD NEW MEMBER ==========" << endl;
        cout << "Enter Member ID: ";
        cin >> id;
        
        if (findMember(id) != nullptr) {
            cout << "Member with ID " << id << " already exists!" << endl;
            return;
        }
        
        cin.ignore();
        cout << "Enter Name: ";
        getline(cin, name);
        cout << "Enter Email: ";
        getline(cin, email);
        cout << "Enter Phone: ";
        getline(cin, phone);
        
        members.emplace_back(id, name, email, phone);
        cout << "Member added successfully!" << endl;
    }
    
    Book* findBook(const string& isbn) {
        auto it = find_if(books.begin(), books.end(),
                         [&isbn](const Book& b) { return b.isbn == isbn; });
        return it != books.end() ? &(*it) : nullptr;
    }
    
    Member* findMember(const string& id) {
        auto it = find_if(members.begin(), members.end(),
                         [&id](const Member& m) { return m.memberId == id; });
        return it != members.end() ? &(*it) : nullptr;
    }
    
    void borrowBook() {
        string isbn, memberId;
        
        cout << "\n========== BORROW BOOK ==========" << endl;
        cout << "Enter ISBN: ";
        cin >> isbn;
        cout << "Enter Member ID: ";
        cin >> memberId;
        
        Book* book = findBook(isbn);
        Member* member = findMember(memberId);
        
        if (!book) {
            cout << "Book not found!" << endl;
            return;
        }
        
        if (!member) {
            cout << "Member not found!" << endl;
            return;
        }
        
        if (!book->isAvailable) {
            cout << "Book is already borrowed!" << endl;
            return;
        }
        
        if (member->fineAmount > 0) {
            cout << "Member has outstanding fines: $" 
                 << fixed << setprecision(2) << member->fineAmount 
                 << ". Please pay fines before borrowing." << endl;
            return;
        }
        
        book->borrowBook(memberId);
        member->addBorrowedBook(isbn);
        
        cout << "Book borrowed successfully!" << endl;
        cout << "Due date: " << book->dueDate << endl;
    }
    
    void returnBook() {
        string isbn;
        
        cout << "\n========== RETURN BOOK ==========" << endl;
        cout << "Enter ISBN: ";
        cin >> isbn;
        
        Book* book = findBook(isbn);
        if (!book) {
            cout << "Book not found!" << endl;
            return;
        }
        
        if (book->isAvailable) {
            cout << "Book is not currently borrowed!" << endl;
            return;
        }
        
        Member* member = findMember(book->borrowedBy);
        if (member) {
            member->removeBorrowedBook(isbn);
        }
        
        book->returnBook();
        cout << "Book returned successfully!" << endl;
    }
    
    void searchBooks() {
        cout << "\n========== SEARCH BOOKS ==========" << endl;
        cout << "1. Search by Title" << endl;
        cout << "2. Search by Author" << endl;
        cout << "3. Search by Genre" << endl;
        cout << "4. Search by ISBN" << endl;
        cout << "Enter search type: ";
        
        int choice;
        cin >> choice;
        cin.ignore();
        
        string query;
        cout << "Enter search term: ";
        getline(cin, query);
        
        vector<Book*> results;
        
        for (auto& book : books) {
            bool match = false;
            switch (choice) {
                case 1: match = book.title.find(query) != string::npos; break;
                case 2: match = book.author.find(query) != string::npos; break;
                case 3: match = book.genre.find(query) != string::npos; break;
                case 4: match = book.isbn == query; break;
            }
            if (match) results.push_back(&book);
        }
        
        if (results.empty()) {
            cout << "No books found matching your search." << endl;
        } else {
            cout << "\nSearch Results:" << endl;
            cout << left << setw(15) << "ISBN" 
                 << setw(30) << "Title" 
                 << setw(20) << "Author" 
                 << setw(15) << "Genre" 
                 << "Status" << endl;
            cout << string(90, '-') << endl;
            
            for (auto* book : results) {
                book->displayBook();
            }
        }
    }
    
    void viewReports() {
        cout << "\n========== LIBRARY REPORTS ==========" << endl;
        
        int totalBooks = books.size();
        int availableBooks = count_if(books.begin(), books.end(),
                                     [](const Book& b) { return b.isAvailable; });
        int borrowedBooks = totalBooks - availableBooks;
        
        cout << "Total Books: " << totalBooks << endl;
        cout << "Available Books: " << availableBooks << endl;
        cout << "Borrowed Books: " << borrowedBooks << endl;
        cout << "Total Members: " << members.size() << endl;
        
        double totalFines = 0.0;
        for (const auto& member : members) {
            totalFines += member.fineAmount;
        }
        cout << "Total Outstanding Fines: $" << fixed << setprecision(2) << totalFines << endl;
        cout << "======================================" << endl;
    }
    
    void saveData() {
        // Save books to file
        ofstream bookFile(booksFile);
        if (bookFile.is_open()) {
            for (const auto& book : books) {
                bookFile << book.isbn << "|" << book.title << "|" 
                         << book.author << "|" << book.genre << "|" 
                         << book.isAvailable << "|" << book.borrowedBy << endl;
            }
            bookFile.close();
        }
    }
    
    void loadData() {
        // Load books from file
        ifstream bookFile(booksFile);
        if (bookFile.is_open()) {
            string line;
            while (getline(bookFile, line)) {
                // Simple parsing implementation
                size_t pos = 0;
                vector<string> tokens;
                string token;
                
                while ((pos = line.find('|')) != string::npos) {
                    token = line.substr(0, pos);
                    tokens.push_back(token);
                    line.erase(0, pos + 1);
                }
                tokens.push_back(line);
                
                if (tokens.size() >= 4) {
                    Book book(tokens[0], tokens[1], tokens[2], tokens[3]);
                    if (tokens.size() >= 6) {
                        book.isAvailable = (tokens[4] == "1");
                        book.borrowedBy = tokens[5];
                    }
                    books.push_back(book);
                }
            }
            bookFile.close();
        }
    }
    
    void run() {
        cout << "Welcome to Library Management System!" << endl;
        
        int choice;
        bool running = true;
        
        while (running) {
            displayMainMenu();
            cin >> choice;
            
            switch (choice) {
                case 1: {
                    cout << "\n1. Add Book  2. Display Books" << endl;
                    cout << "Enter choice: ";
                    int bookChoice;
                    cin >> bookChoice;
                    if (bookChoice == 1) addBook();
                    else if (bookChoice == 2) displayAllBooks();
                    break;
                }
                case 2: {
                    cout << "\n1. Add Member  2. Display Members" << endl;
                    cout << "Enter choice: ";
                    int memberChoice;
                    cin >> memberChoice;
                    if (memberChoice == 1) addMember();
                    // Display members implementation can be added
                    break;
                }
                case 3: borrowBook(); break;
                case 4: returnBook(); break;
                case 5: searchBooks(); break;
                case 6: viewReports(); break;
                case 7: cout << "Fine management feature available." << endl; break;
                case 8:
                    cout << "Thank you for using Library Management System!" << endl;
                    running = false;
                    break;
                default:
                    cout << "Invalid choice! Please try again." << endl;
            }
            
            if (running && choice != 8) {
                cout << "\nPress Enter to continue...";
                cin.ignore();
                cin.get();
            }
        }
    }
};

int main() {
    LibraryManagementSystem lms;
    lms.run();
    return 0;
}

Note: This is a simplified version. The complete implementation would include more advanced features like database integration, user authentication, and a graphical interface.

Simple File Manager

Create a console-based file manager with basic file operations.

Features:

  • Directory navigation
  • File and folder listing
  • File creation, copying, and deletion
  • File size and date information
  • Search functionality
  • Text file viewing and editing
file_manager.cpp
#include <iostream>
#include <fstream>
#include <filesystem>
#include <string>
#include <vector>
#include <algorithm>
#include <iomanip>
#include <ctime>
using namespace std;
using namespace filesystem;

class FileManager {
private:
    path currentDirectory;
    
public:
    FileManager() {
        currentDirectory = current_path();
    }
    
    void displayMainMenu() {
        cout << "\n========== FILE MANAGER ==========" << endl;
        cout << "Current Directory: " << currentDirectory << endl;
        cout << "1. List Files and Directories" << endl;
        cout << "2. Change Directory" << endl;
        cout << "3. Create File" << endl;
        cout << "4. Create Directory" << endl;
        cout << "5. Copy File" << endl;
        cout << "6. Move/Rename File" << endl;
        cout << "7. Delete File/Directory" << endl;
        cout << "8. View File Content" << endl;
        cout << "9. Edit File" << endl;
        cout << "10. Search Files" << endl;
        cout << "11. File Information" << endl;
        cout << "12. Go to Parent Directory" << endl;
        cout << "13. Exit" << endl;
        cout << "==================================" << endl;
        cout << "Enter your choice: ";
    }
    
    void listDirectory() {
        cout << "\n========== DIRECTORY LISTING ==========" << endl;
        cout << "Current Directory: " << currentDirectory << endl;
        cout << string(60, '-') << endl;
        
        try {
            cout << left << setw(30) << "Name" 
                 << setw(8) << "Type" 
                 << setw(12) << "Size" 
                 << "Last Modified" << endl;
            cout << string(60, '-') << endl;
            
            vector<directory_entry> entries;
            for (const auto& entry : directory_iterator(currentDirectory)) {
                entries.push_back(entry);
            }
            
            // Sort entries: directories first, then files
            sort(entries.begin(), entries.end(), [](const directory_entry& a, const directory_entry& b) {
                if (a.is_directory() != b.is_directory()) {
                    return a.is_directory();
                }
                return a.path().filename() < b.path().filename();
            });
            
            for (const auto& entry : entries) {
                string name = entry.path().filename().string();
                string type = entry.is_directory() ? "DIR" : "FILE";
                string size = entry.is_directory() ? "-" : to_string(entry.file_size()) + " B";
                
                auto ftime = entry.last_write_time();
                auto sctp = time_point_cast<system_clock::duration>(ftime - file_time_type::clock::now() + system_clock::now());
                auto cftime = system_clock::to_time_t(sctp);
                
                cout << left << setw(30) << (name.length() > 29 ? name.substr(0, 26) + "..." : name)
                     << setw(8) << type
                     << setw(12) << size
                     << put_time(localtime(&cftime), "%Y-%m-%d %H:%M") << endl;
            }
            
        } catch (const exception& e) {
            cout << "Error accessing directory: " << e.what() << endl;
        }
        cout << "=======================================" << endl;
    }
    
    void changeDirectory() {
        string dirName;
        cout << "\nEnter directory name (or '..' for parent, '/' for root): ";
        cin.ignore();
        getline(cin, dirName);
        
        try {
            path newPath;
            if (dirName == "..") {
                newPath = currentDirectory.parent_path();
            } else if (dirName == "/") {
                newPath = path("/");
            } else if (dirName.front() == '/' || (dirName.length() > 1 && dirName[1] == ':')) {
                // Absolute path
                newPath = path(dirName);
            } else {
                // Relative path
                newPath = currentDirectory / dirName;
            }
            
            if (exists(newPath) && is_directory(newPath)) {
                currentDirectory = newPath;
                cout << "Changed directory to: " << currentDirectory << endl;
            } else {
                cout << "Directory does not exist!" << endl;
            }
        } catch (const exception& e) {
            cout << "Error changing directory: " << e.what() << endl;
        }
    }
    
    void createFile() {
        string fileName;
        cout << "\nEnter file name: ";
        cin.ignore();
        getline(cin, fileName);
        
        path filePath = currentDirectory / fileName;
        
        if (exists(filePath)) {
            cout << "File already exists!" << endl;
            return;
        }
        
        cout << "Enter file content (press Ctrl+D or Ctrl+Z to finish):" << endl;
        
        ofstream file(filePath);
        if (file.is_open()) {
            string line;
            while (getline(cin, line)) {
                file << line << endl;
            }
            file.close();
            cout << "File created successfully!" << endl;
            cin.clear(); // Clear EOF flag
        } else {
            cout << "Error creating file!" << endl;
        }
    }
    
    void createDirectory() {
        string dirName;
        cout << "\nEnter directory name: ";
        cin.ignore();
        getline(cin, dirName);
        
        path dirPath = currentDirectory / dirName;
        
        try {
            if (create_directory(dirPath)) {
                cout << "Directory created successfully!" << endl;
            } else {
                cout << "Directory already exists or could not be created!" << endl;
            }
        } catch (const exception& e) {
            cout << "Error creating directory: " << e.what() << endl;
        }
    }
    
    void copyFile() {
        string source, destination;
        cout << "\nEnter source file name: ";
        cin.ignore();
        getline(cin, source);
        cout << "Enter destination file name: ";
        getline(cin, destination);
        
        path sourcePath = currentDirectory / source;
        path destPath = currentDirectory / destination;
        
        try {
            if (!exists(sourcePath)) {
                cout << "Source file does not exist!" << endl;
                return;
            }
            
            if (exists(destPath)) {
                cout << "Destination file already exists! Overwrite? (y/n): ";
                char choice;
                cin >> choice;
                if (choice != 'y' && choice != 'Y') {
                    return;
                }
            }
            
            copy_file(sourcePath, destPath, copy_options::overwrite_existing);
            cout << "File copied successfully!" << endl;
            
        } catch (const exception& e) {
            cout << "Error copying file: " << e.what() << endl;
        }
    }
    
    void moveFile() {
        string source, destination;
        cout << "\nEnter source file name: ";
        cin.ignore();
        getline(cin, source);
        cout << "Enter destination file name: ";
        getline(cin, destination);
        
        path sourcePath = currentDirectory / source;
        path destPath = currentDirectory / destination;
        
        try {
            if (!exists(sourcePath)) {
                cout << "Source file does not exist!" << endl;
                return;
            }
            
            rename(sourcePath, destPath);
            cout << "File moved/renamed successfully!" << endl;
            
        } catch (const exception& e) {
            cout << "Error moving file: " << e.what() << endl;
        }
    }
    
    void deleteFileOrDirectory() {
        string name;
        cout << "\nEnter file/directory name to delete: ";
        cin.ignore();
        getline(cin, name);
        
        path targetPath = currentDirectory / name;
        
        try {
            if (!exists(targetPath)) {
                cout << "File/directory does not exist!" << endl;
                return;
            }
            
            cout << "Are you sure you want to delete '" << name << "'? (y/n): ";
            char choice;
            cin >> choice;
            
            if (choice == 'y' || choice == 'Y') {
                if (is_directory(targetPath)) {
                    remove_all(targetPath);
                    cout << "Directory deleted successfully!" << endl;
                } else {
                    remove(targetPath);
                    cout << "File deleted successfully!" << endl;
                }
            } else {
                cout << "Deletion cancelled." << endl;
            }
            
        } catch (const exception& e) {
            cout << "Error deleting: " << e.what() << endl;
        }
    }
    
    void viewFile() {
        string fileName;
        cout << "\nEnter file name: ";
        cin.ignore();
        getline(cin, fileName);
        
        path filePath = currentDirectory / fileName;
        
        if (!exists(filePath) || is_directory(filePath)) {
            cout << "File does not exist or is a directory!" << endl;
            return;
        }
        
        ifstream file(filePath);
        if (file.is_open()) {
            cout << "\n========== FILE CONTENT ==========" << endl;
            cout << "File: " << fileName << endl;
            cout << string(40, '-') << endl;
            
            string line;
            int lineNumber = 1;
            while (getline(file, line)) {
                cout << setw(4) << lineNumber++ << ": " << line << endl;
            }
            file.close();
            cout << "==================================" << endl;
        } else {
            cout << "Error opening file!" << endl;
        }
    }
    
    void editFile() {
        string fileName;
        cout << "\nEnter file name: ";
        cin.ignore();
        getline(cin, fileName);
        
        path filePath = currentDirectory / fileName;
        
        // First, show current content if file exists
        if (exists(filePath) && !is_directory(filePath)) {
            cout << "\nCurrent file content:" << endl;
            viewFile();
        }
        
        cout << "\nEnter new content (press Ctrl+D or Ctrl+Z on empty line to finish):" << endl;
        
        ofstream file(filePath);
        if (file.is_open()) {
            string line;
            while (getline(cin, line)) {
                file << line << endl;
            }
            file.close();
            cout << "File saved successfully!" << endl;
            cin.clear(); // Clear EOF flag
        } else {
            cout << "Error opening file for editing!" << endl;
        }
    }
    
    void searchFiles() {
        string pattern;
        cout << "\nEnter search pattern (filename): ";
        cin.ignore();
        getline(cin, pattern);
        
        cout << "\nSearch results for '" << pattern << "':" << endl;
        cout << string(50, '-') << endl;
        
        try {
            bool found = false;
            for (const auto& entry : recursive_directory_iterator(currentDirectory)) {
                string filename = entry.path().filename().string();
                if (filename.find(pattern) != string::npos) {
                    cout << (entry.is_directory() ? "[DIR] " : "[FILE] ")
                         << entry.path() << endl;
                    found = true;
                }
            }
            
            if (!found) {
                cout << "No files found matching the pattern." << endl;
            }
            
        } catch (const exception& e) {
            cout << "Error during search: " << e.what() << endl;
        }
        cout << string(50, '-') << endl;
    }
    
    void fileInfo() {
        string fileName;
        cout << "\nEnter file/directory name: ";
        cin.ignore();
        getline(cin, fileName);
        
        path filePath = currentDirectory / fileName;
        
        try {
            if (!exists(filePath)) {
                cout << "File/directory does not exist!" << endl;
                return;
            }
            
            cout << "\n========== FILE INFORMATION ==========" << endl;
            cout << "Name: " << filePath.filename() << endl;
            cout << "Full Path: " << absolute(filePath) << endl;
            cout << "Type: " << (is_directory(filePath) ? "Directory" : "File") << endl;
            
            if (!is_directory(filePath)) {
                cout << "Size: " << file_size(filePath) << " bytes" << endl;
            }
            
            auto ftime = last_write_time(filePath);
            auto sctp = time_point_cast<system_clock::duration>(ftime - file_time_type::clock::now() + system_clock::now());
            auto cftime = system_clock::to_time_t(sctp);
            
            cout << "Last Modified: " << put_time(localtime(&cftime), "%Y-%m-%d %H:%M:%S") << endl;
            
            // Permissions (simplified)
            auto perms = status(filePath).permissions();
            cout << "Permissions: ";
            cout << ((perms & perms::owner_read) != perms::none ? "r" : "-");
            cout << ((perms & perms::owner_write) != perms::none ? "w" : "-");
            cout << ((perms & perms::owner_exec) != perms::none ? "x" : "-");
            cout << endl;
            
            cout << "======================================" << endl;
            
        } catch (const exception& e) {
            cout << "Error getting file information: " << e.what() << endl;
        }
    }
    
    void goToParent() {
        path parent = currentDirectory.parent_path();
        if (parent != currentDirectory) {
            currentDirectory = parent;
            cout << "Moved to parent directory: " << currentDirectory << endl;
        } else {
            cout << "Already at root directory!" << endl;
        }
    }
    
    void run() {
        cout << "Welcome to Simple File Manager!" << endl;
        cout << "Note: This program requires C++17 or later for filesystem support." << endl;
        
        int choice;
        bool running = true;
        
        while (running) {
            displayMainMenu();
            cin >> choice;
            
            switch (choice) {
                case 1: listDirectory(); break;
                case 2: changeDirectory(); break;
                case 3: createFile(); break;
                case 4: createDirectory(); break;
                case 5: copyFile(); break;
                case 6: moveFile(); break;
                case 7: deleteFileOrDirectory(); break;
                case 8: viewFile(); break;
                case 9: editFile(); break;
                case 10: searchFiles(); break;
                case 11: fileInfo(); break;
                case 12: goToParent(); break;
                case 13:
                    cout << "Thank you for using File Manager!" << endl;
                    running = false;
                    break;
                default:
                    cout << "Invalid choice! Please try again." << endl;
            }
            
            if (running && choice != 13) {
                cout << "\nPress Enter to continue...";
                cin.ignore();
                cin.get();
            }
        }
    }
};

int main() {
    FileManager fm;
    fm.run();
    return 0;
}

Note: This project demonstrates file I/O operations, directory manipulation, and system programming concepts in C++. Requires C++17 or later for filesystem support.