|
|
#include "file_manager.h"
|
|
|
|
|
|
#include <iostream>
|
|
|
#include <fstream>
|
|
|
#include <ctime>
|
|
|
#include <string>
|
|
|
#include <vector>
|
|
|
#include <direct.h> // Windows目录操作
|
|
|
#include <windows.h> // Windows API
|
|
|
#include <unordered_map>
|
|
|
|
|
|
std::string FileManager::UsernameToPinyin(const std::string& username) {
|
|
|
// 用户名到拼音的映射
|
|
|
static const std::unordered_map<std::string, std::string> name_map = {
|
|
|
{"张三1", "zhangsan1"},
|
|
|
{"张三2", "zhangsan2"},
|
|
|
{"张三3", "zhangsan3"},
|
|
|
{"李四1", "lisi1"},
|
|
|
{"李四2", "lisi2"},
|
|
|
{"李四3", "lisi3"},
|
|
|
{"王五1", "wangwu1"},
|
|
|
{"王五2", "wangwu2"},
|
|
|
{"王五3", "wangwu3"}
|
|
|
};
|
|
|
|
|
|
auto it = name_map.find(username);
|
|
|
if (it != name_map.end()) {
|
|
|
return it->second;
|
|
|
}
|
|
|
|
|
|
// 如果没有找到映射,返回原用户名
|
|
|
return username;
|
|
|
}
|
|
|
|
|
|
bool FileManager::CreateUserDirectory(const std::string& username) {
|
|
|
std::string pinyin_username = UsernameToPinyin(username);
|
|
|
const std::string dir_path = std::string(kBasePath) + pinyin_username;
|
|
|
|
|
|
// 先创建基础目录(如果不存在)
|
|
|
_mkdir(kBasePath);
|
|
|
|
|
|
// 使用Windows API创建用户目录
|
|
|
if (CreateDirectoryA(dir_path.c_str(), NULL)) {
|
|
|
return true;
|
|
|
} else {
|
|
|
// 如果目录已存在,ERROR_ALREADY_EXISTS是正常的
|
|
|
return GetLastError() == ERROR_ALREADY_EXISTS;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
std::string FileManager::GenerateFilename() {
|
|
|
std::time_t now = std::time(nullptr);
|
|
|
std::tm local_time;
|
|
|
localtime_s(&local_time, &now); // 使用安全的版本
|
|
|
|
|
|
char buffer[80];
|
|
|
std::strftime(buffer, sizeof(buffer), "%Y%m%d_%H%M%S", &local_time);
|
|
|
return std::string(buffer) + ".txt";
|
|
|
}
|
|
|
|
|
|
bool FileManager::SaveQuestions(const std::string& username,
|
|
|
const std::vector<std::string>& questions) {
|
|
|
if (questions.empty()) {
|
|
|
std::cerr << "错误:问题列表为空" << std::endl;
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 确保用户目录存在
|
|
|
if (!CreateUserDirectory(username)) {
|
|
|
std::cerr << "错误:无法创建用户目录: " << username << std::endl;
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
std::string pinyin_username = UsernameToPinyin(username);
|
|
|
const std::string dir_path = std::string(kBasePath) + pinyin_username;
|
|
|
const std::string filename = GenerateFilename();
|
|
|
const std::string full_path = dir_path + "\\" + filename;
|
|
|
|
|
|
std::ofstream file(full_path);
|
|
|
if (!file.is_open()) {
|
|
|
std::cerr << "错误:无法创建文件: " << full_path << std::endl;
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 写入文件头信息
|
|
|
file << "用户名: " << username << " (" << pinyin_username << ")\n";
|
|
|
file << "生成时间: " << filename.substr(0, filename.length() - 4) << "\n";
|
|
|
file << "题目数量: " << questions.size() << "\n";
|
|
|
file << "==============================\n\n";
|
|
|
|
|
|
// 写入题目
|
|
|
for (size_t i = 0; i < questions.size(); ++i) {
|
|
|
file << "第" << (i + 1) << "题: " << questions[i] << "\n\n";
|
|
|
}
|
|
|
|
|
|
file.close();
|
|
|
std::cout << "✓ 题目已保存至: " << full_path << std::endl;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool FileManager::IsQuestionExists(const std::string& username,
|
|
|
const std::string& question) {
|
|
|
const auto existing_questions = LoadExistingQuestions(username);
|
|
|
|
|
|
// 简单的字符串匹配(可改进为模糊匹配)
|
|
|
for (const auto& existing : existing_questions) {
|
|
|
if (existing.find(question) != std::string::npos ||
|
|
|
question.find(existing) != std::string::npos) {
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
std::vector<std::string> FileManager::LoadExistingQuestions(const std::string& username) {
|
|
|
std::vector<std::string> questions;
|
|
|
std::string pinyin_username = UsernameToPinyin(username);
|
|
|
const std::string dir_path = std::string(kBasePath) + pinyin_username;
|
|
|
const std::string search_path = dir_path + "\\*.txt";
|
|
|
|
|
|
// 检查目录是否存在
|
|
|
DWORD attrib = GetFileAttributesA(dir_path.c_str());
|
|
|
if (attrib == INVALID_FILE_ATTRIBUTES || !(attrib & FILE_ATTRIBUTE_DIRECTORY)) {
|
|
|
return questions; // 目录不存在
|
|
|
}
|
|
|
|
|
|
WIN32_FIND_DATAA find_file_data;
|
|
|
HANDLE h_find = FindFirstFileA(search_path.c_str(), &find_file_data);
|
|
|
|
|
|
if (h_find == INVALID_HANDLE_VALUE) {
|
|
|
return questions; // 没有找到文件
|
|
|
}
|
|
|
|
|
|
do {
|
|
|
if (!(find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
|
|
const std::string filename = find_file_data.cFileName;
|
|
|
const std::string file_path = dir_path + "\\" + filename;
|
|
|
|
|
|
std::ifstream file(file_path);
|
|
|
if (file.is_open()) {
|
|
|
std::string line;
|
|
|
bool in_questions_section = false;
|
|
|
|
|
|
while (std::getline(file, line)) {
|
|
|
// 跳过文件头,直到分隔线
|
|
|
if (line.find("==============================") != std::string::npos) {
|
|
|
in_questions_section = true;
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
if (in_questions_section && !line.empty()) {
|
|
|
// 匹配 "第X题: " 格式
|
|
|
if (line.find("第") == 0 && line.find("题: ") != std::string::npos) {
|
|
|
size_t pos = line.find("题: ");
|
|
|
if (pos != std::string::npos) {
|
|
|
std::string question_text = line.substr(pos + 3); // "题: " 长度是3
|
|
|
// 移除Windows换行符
|
|
|
if (!question_text.empty() && question_text.back() == '\r') {
|
|
|
question_text.pop_back();
|
|
|
}
|
|
|
if (!question_text.empty()) {
|
|
|
questions.push_back(question_text);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
file.close();
|
|
|
}
|
|
|
}
|
|
|
} while (FindNextFileA(h_find, &find_file_data) != 0);
|
|
|
|
|
|
FindClose(h_find);
|
|
|
return questions;
|
|
|
} |