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
#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
#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
#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
#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
#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
#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.