个人日记

支持的功能:

  • 是否创建新日记
    • 命名格式为:名称 + 日期
    • 添加标题
    • 添加内容
  • 是否查找日记
    • 查找关键词:日期

代码

/* DiaryApp.cpp */
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
#include <vector>
#include <algorithm>
#include <ctime>

// 定义DiaryEntry抽象基类,包含虚函数save()和display()
class DiaryEntry {
public:
    std::string title;
    std::string content;
    std::string date;  // 格式为 "YYYY-MM-DD"

    DiaryEntry(const std::string& title, const std::string& content, const std::string& date)
        : title(title), content(content), date(date) {}

    virtual ~DiaryEntry() {}

    // 保存日记的方法,子类需要重写该方法,实现不同的存储策略
    virtual void save() const = 0;

    // 显示日记内容
    virtual void display() const = 0;
};

// 一个基于文件存储的日记条目类
class FileDiaryEntry : public DiaryEntry {
public:
    std::string filename;

    FileDiaryEntry(const std::string& title, const std::string& content, 
                   const std::string& date, const std::string& filename)
        : DiaryEntry(title, content, date), filename(filename) {}

    // 保存日记到文件中,如果文件打开失败则抛出异常
    virtual void save() const override {
        std::ofstream ofs(filename, std::ios::app);
        if (!ofs) {
            throw std::runtime_error("无法打开文件:" + filename);
        }
        ofs << "date: " << date << "\n"
            << "title: " << title << "\n"
            << "content: " << content << "\n"
            << "--------------------------------\n";
        ofs.close();
    }

    // 输出日记内容到控制台
    virtual void display() const override {
        std::cout << "date: " << date << "\n"
                 << "title: " << title << "\n"
                 << "content: " << content << "\n";
    }
};

// 搜索(根据日期搜索日记条目)的简单实现:从文件读取所有日记,并按匹配日期筛选
std::vector<std::string> searchDiaryByDate(const std::string& filename, const std::string& targetDate) {
    std::ifstream ifs(filename);
    std::vector<std::string> results;
    
    if (!ifs) {
        throw std::runtime_error("无法打开文件:" + filename);
    }

    std::string line;
    std::string entry;
    bool match = false;

    while (std::getline(ifs, line)) {
        if (line.find("date:") != std::string::npos) {
            // 每个新的日记条目开始时,先判断上一个条目是否匹配
            if (match && !entry.empty()) {
                results.push_back(entry);
            }
            entry = line + "\n";
            // 检查日期是否匹配
            match = (line.find(targetDate) != std::string::npos);
        } else {
            entry += line + "\n";
        }
    }

    // 最后一个条目的判断
    if (match && !entry.empty()) {
        results.push_back(entry);
    }

    ifs.close();
    return results;
}

int main() {
    std::cout << "欢迎使用日记本" << std::endl;

    try {
        std::cout << "要写日记吗?(y/n): ";
        char choice;
        std::cin >> choice;
        std::cin.ignore();

        if (choice == 'y' || choice == 'Y') {
            std::cout << "请输入日记标题: ";
            std::string title;
            std::getline(std::cin, title);

            std::cout << "请输入日记内容: ";
            std::string content;
            std::getline(std::cin, content);

            std::cout << "请输入日记日期: ";
            std::string date;
            std::getline(std::cin, date);

            const std::string filename = "diary_" + date + ".md";
            
            // 创建日记条目并保存
            FileDiaryEntry entry1(title, content, date, filename);
            entry1.save();
            entry1.display();
            std::cout << "保存成功" << std::endl;
        } else {
            std::cout << "没有新日记" << std::endl;
        }

        std::cout << "是否继续搜索?(y/n): ";
        std::cin >> choice;
        std::cin.ignore();

        if (choice == 'y' || choice == 'Y') {
            std::cout << "请输入搜索日期: ";
            std::string targetDate;
            std::getline(std::cin, targetDate);

            // 搜索指定日期的日记条目
            std::vector<std::string> diaryEntries = searchDiaryByDate("diary_" + targetDate + ".md", targetDate);
            std::cout << "\n搜索日期 " << targetDate << " 的日记条目:\n";
            
            for (const auto& de : diaryEntries) {
                std::cout << de << "\n";
            }
        }
    } catch (const std::exception& ex) {
        std::cerr << "错误: " << ex.what() << std::endl;
        return 1;
    }

    return 0;
}