C++20 基于文本文件的类对象增删查改系统

C++20 基于文本文件的类对象增删查改系统

cpp 复制代码
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <ranges>
#include <string>
#include <sstream>
#include <filesystem>

namespace fs = std::filesystem;

// 定义Person类
class Person {
public:
    Person() = default;
    Person(int id, const std::string& name, int age, const std::string& email)
        : id(id), name(name), age(age), email(email) {
    }

    // 序列化为字符串
    std::string serialize() const {
        std::ostringstream oss;
        oss << id << "," << name << "," << age << "," << email;
        return oss.str();
    }

    // 从字符串反序列化
    static Person deserialize(const std::string& data) {
        std::istringstream iss(data);
        std::string token;
        std::vector<std::string> tokens;

        while (std::getline(iss, token, ',')) {
            tokens.push_back(token);
        }

        if (tokens.size() != 4) {
            throw std::runtime_error("Invalid data format");
        }

        int id = std::stoi(tokens[0]);
        int age = std::stoi(tokens[2]);
        return Person(id, tokens[1], age, tokens[3]);
    }

    // 重载输出运算符
    friend std::ostream& operator<<(std::ostream& os, const Person& p) {
        os << "ID: " << p.id << ", Name: " << p.name
            << ", Age: " << p.age << ", Email: " << p.email;
        return os;
    }

    // 获取ID
    int getId() const { return id; }

    // 设置属性
    void setName(const std::string& newName) { name = newName; }
    void setAge(int newAge) { age = newAge; }
    void setEmail(const std::string& newEmail) { email = newEmail; }

private:
    int id;
    std::string name;
    int age;
    std::string email;
};

// 数据存储管理器
class DataManager {
public:
    explicit DataManager(const std::string& filename) : filename(filename) {
        loadFromFile();
    }

    ~DataManager() {
        saveToFile();
    }

    // 添加Person
    void addPerson(const Person& person) {
        persons.push_back(person);
        saveToFile();
    }

    // 删除Person
    bool deletePerson(int id) {
        auto it = std::ranges::find_if(persons, [id](const Person& p) {
            return p.getId() == id;
            });

        if (it != persons.end()) {
            persons.erase(it);
            saveToFile();
            return true;
        }
        return false;
    }

    // 查找Person
    Person* findPerson(int id) {
        auto it = std::ranges::find_if(persons, [id](const Person& p) {
            return p.getId() == id;
            });

        if (it != persons.end()) {
            return &(*it);
        }
        return nullptr;
    }

    // 更新Person
    bool updatePerson(int id, const std::string& name, int age, const std::string& email) {
        Person* person = findPerson(id);
        if (person) {
            person->setName(name);
            person->setAge(age);
            person->setEmail(email);
            saveToFile();
            return true;
        }
        return false;
    }

    // 显示所有Person
    void displayAll() const {
        if (persons.empty()) {
            std::cout << "No persons in the database.\n";
            return;
        }

        for (const auto& person : persons) {
            std::cout << person << '\n';
        }
    }

    // 获取所有Person
    const std::vector<Person>& getAllPersons() const {
        return persons;
    }

private:
    std::vector<Person> persons;
    std::string filename;

    // 从文件加载数据
    void loadFromFile() {
        if (!fs::exists(filename)) {
            return;
        }

        std::ifstream file(filename);
        if (!file.is_open()) {
            throw std::runtime_error("Cannot open file: " + filename);
        }

        std::string line;
        while (std::getline(file, line)) {
            if (!line.empty()) {
                try {
                    persons.push_back(Person::deserialize(line));
                }
                catch (const std::exception& e) {
                    std::cerr << "Error parsing line: " << line << " - " << e.what() << '\n';
                }
            }
        }
        file.close();
    }

    // 保存数据到文件
    void saveToFile() {
        std::ofstream file(filename);
        if (!file.is_open()) {
            throw std::runtime_error("Cannot open file: " + filename);
        }

        for (const auto& person : persons) {
            file << person.serialize() << '\n';
        }
        file.close();
    }
};

// 显示菜单
void displayMenu() {
    std::cout << "\n=== Person Management System ===\n";
    std::cout << "1. Add Person\n";
    std::cout << "2. Delete Person\n";
    std::cout << "3. Find Person\n";
    std::cout << "4. Update Person\n";
    std::cout << "5. Display All Persons\n";
    std::cout << "6. Exit\n";
    std::cout << "Choose an option: ";
}

int main() {
    DataManager dm("persons.txt");

    int choice;
    do {
        displayMenu();
        std::cin >> choice;
        std::cin.ignore(); // 忽略换行符

        switch (choice) {
        case 1: {
            int id, age;
            std::string name, email;

            std::cout << "Enter ID: ";
            std::cin >> id;
            std::cin.ignore();

            std::cout << "Enter Name: ";
            std::getline(std::cin, name);

            std::cout << "Enter Age: ";
            std::cin >> age;
            std::cin.ignore();

            std::cout << "Enter Email: ";
            std::getline(std::cin, email);

            dm.addPerson(Person(id, name, age, email));
            std::cout << "Person added successfully.\n";
            break;
        }
        case 2: {
            int id;
            std::cout << "Enter ID to delete: ";
            std::cin >> id;

            if (dm.deletePerson(id)) {
                std::cout << "Person deleted successfully.\n";
            }
            else {
                std::cout << "Person not found.\n";
            }
            break;
        }
        case 3: {
            int id;
            std::cout << "Enter ID to find: ";
            std::cin >> id;

            Person* person = dm.findPerson(id);
            if (person) {
                std::cout << "Person found: " << *person << '\n';
            }
            else {
                std::cout << "Person not found.\n";
            }
            break;
        }
        case 4: {
            int id, age;
            std::string name, email;

            std::cout << "Enter ID to update: ";
            std::cin >> id;
            std::cin.ignore();

            std::cout << "Enter new Name: ";
            std::getline(std::cin, name);

            std::cout << "Enter new Age: ";
            std::cin >> age;
            std::cin.ignore();

            std::cout << "Enter new Email: ";
            std::getline(std::cin, email);

            if (dm.updatePerson(id, name, age, email)) {
                std::cout << "Person updated successfully.\n";
            }
            else {
                std::cout << "Person not found.\n";
            }
            break;
        }
        case 5:
            dm.displayAll();
            break;
        case 6:
            std::cout << "Exiting...\n";
            break;
        default:
            std::cout << "Invalid option. Please try again.\n";
        }
    } while (choice != 6);

    return 0;
}
相关推荐
启观川16 小时前
数据结构与算法 -第 3 章 常用算法-动态规划
数据结构·笔记·python·算法
码爸16 小时前
排序算法介绍
python·算法·排序算法
动词ing17 小时前
【题目练习】算法 组合总和||
算法
longlongzihan17 小时前
链表找环:Floyd 判圈算法(LeetCode 141 & 142 )
c++·算法·leetcode·链表
专业程序开发源17 小时前
flask家电故障预测系统92491-计算机课程设计/毕业设计
vscode·python·sql·算法·flask·课程设计
Logic10117 小时前
C语言/数据结构欧几里得算法题解:长方形切割最大正方形——贪心划分计数
c语言·数据结构·算法·贪心算法·时间复杂度·空间复杂度·欧几里得算法
yi01118 小时前
LeetCode 643. 子数组最大平均数 I|从暴力枚举到滑动窗口
人工智能·笔记·python·算法·leetcode·滑动窗口
极光通讯18 小时前
服务器内存来料检验(IQC)实操:批次追溯、外观判定与上机验证
java·服务器·算法
淡海水19 小时前
02-04-原理篇-GC Roots与对象图遍历
算法·unity·c#·图·gc·遍历·roots
ClickHouseDB19 小时前
ClickHouse 大规模 OpenTelemetry 数据接入架构的可靠性演进
算法