initial commit

zhouyutong 7 months ago
commit cb3e1d23f9

@ -0,0 +1,94 @@
# 个人项目:中小学数学卷子自动生成程序
## 项目信息
- **班级**[软件2301]
- **姓名**[周禹彤]
- **学号**[202326010102]
- **项目名称**:中小学数学卷子自动生成程序
- **提交时间**2025年9月29日
## 项目简介
本项目是一个命令行界面的中小学数学卷子自动生成程序,主要为小学、初中和高中数学老师提供便捷的题目生成服务。系统支持用户登录验证、题目生成、难度切换、题目查重和文件保存等功能。
## 功能特性
### 1. 用户认证
- 支持小学、初中、高中各三个预设账户登录
- 用户名和密码验证
- 登录成功后显示当前出题类型
### 2. 题目生成
- **小学题目**:支持 +、-、*、/ 四则运算,包含括号
- **初中题目**:至少包含平方或开根号运算符
- **高中题目**:至少包含 sin、cos、tan 三角函数
- 题目数量范围10-30道
- 操作数范围1-100
### 3. 功能操作
- **切换难度**:支持在登录状态下切换小学、初中、高中三种难度
- **题目查重**:检查新生成题目与历史题目是否重复
- **文件保存**:按用户分文件夹保存,文件名格式:年-月-日-时-分-秒.txt
## 项目结构
```plaintext
软件2301_周禹彤_个人项目
├── src
│ ├── main.cpp # 应用程序入口点
│ ├── auth.cpp # 认证系统实现
│ ├── file_manager.cpp # 文件管理器实现
│ ├── question_generator.cpp # 题目生成器实现
│ ├── user.cpp # 用户类实现
│ ├── auth.h # 认证系统头文件
│ ├── file_manager.h # 文件管理器头文件
│ ├── question_generator.h # 题目生成器头文件
│ ├── user.h # 用户类头文件
│ └── utils.h # 工具函数头文件
└── doc
└── README.md # 项目文档
```
## 类设计说明
### 1. AuthSystem (认证系统)
- 负责用户登录验证
- 管理预设用户账户
- 提供用户身份验证功能
### 2. QuestionGenerator (题目生成器)
- 根据难度级别生成相应题目
- 支持小学、初中、高中三种难度
- 确保题目符合各难度要求
### 3. FileManager (文件管理器)
- 处理文件保存操作
- 实现题目查重功能
- 管理用户文件夹结构
### 4. User (用户类)
- 封装用户信息
- 提供用户权限管理
- 支持难度切换
## 编译运行
### 环境要求
- C++17 或更高版本
- GCC 编译器
- 支持文件系统操作的操作系统
### 编译命令
```bash
cd src
make

@ -0,0 +1,40 @@
# Project: 软件2301_周禹彤_个人项目
# Makefile created by Dev-C++ 5.11
CPP = g++.exe
CC = gcc.exe
WINDRES = windres.exe
OBJ = main.o auth.o question_generator.o file_manager.o user.o
LINKOBJ = main.o auth.o question_generator.o file_manager.o user.o
LIBS = -L"D:/Program Files/Dev-Cpp/MinGW64/lib" -L"D:/Program Files/Dev-Cpp/MinGW64/x86_64-w64-mingw32/lib" -static-libgcc
INCS = -I"D:/Program Files/Dev-Cpp/MinGW64/include" -I"D:/Program Files/Dev-Cpp/MinGW64/x86_64-w64-mingw32/include" -I"D:/Program Files/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include"
CXXINCS = -I"D:/Program Files/Dev-Cpp/MinGW64/include" -I"D:/Program Files/Dev-Cpp/MinGW64/x86_64-w64-mingw32/include" -I"D:/Program Files/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include" -I"D:/Program Files/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++"
BIN = 软件2301_周禹彤_个人项目.exe
CXXFLAGS = $(CXXINCS)
CFLAGS = $(INCS)
RM = rm.exe -f
.PHONY: all all-before all-after clean clean-custom
all: all-before $(BIN) all-after
clean: clean-custom
${RM} $(OBJ) $(BIN)
$(BIN): $(OBJ)
$(CPP) $(LINKOBJ) -o $(BIN) $(LIBS)
main.o: main.cpp
$(CPP) -c main.cpp -o main.o $(CXXFLAGS)
auth.o: auth.cpp
$(CPP) -c auth.cpp -o auth.o $(CXXFLAGS)
question_generator.o: question_generator.cpp
$(CPP) -c question_generator.cpp -o question_generator.o $(CXXFLAGS)
file_manager.o: file_manager.cpp
$(CPP) -c file_manager.cpp -o file_manager.o $(CXXFLAGS)
user.o: user.cpp
$(CPP) -c user.cpp -o user.o $(CXXFLAGS)

@ -0,0 +1,43 @@
#include "auth.h"
#include <iostream>
using namespace std;
AuthSystem::AuthSystem() {
// 初始化预设账户
users.push_back(User("张三1", "123", "小学"));
users.push_back(User("张三2", "123", "小学"));
users.push_back(User("张三3", "123", "小学"));
users.push_back(User("李四1", "123", "初中"));
users.push_back(User("李四2", "123", "初中"));
users.push_back(User("李四3", "123", "初中"));
users.push_back(User("王五1", "123", "高中"));
users.push_back(User("王五2", "123", "高中"));
users.push_back(User("王五3", "123", "高中"));
}
User* AuthSystem::login() {
string username, password;
cout << "请输入用户名和密码(用空格隔开):";
cin >> username >> password;
cin.ignore(); // 清除输入缓冲区
for (auto& user : users) {
if (user.getUsername() == username && user.getPassword() == password) {
cout << "当前选择为" << user.getGradeName() << "出题" << endl;
return new User(user); // 返回新对象
}
}
cout << "请输入正确的用户名、密码" << endl;
return nullptr;
}
bool AuthSystem::validateUser(const string& username, const string& password) {
for (const auto& user : users) {
if (user.getUsername() == username && user.getPassword() == password) {
return true;
}
}
return false;
}

@ -0,0 +1,20 @@
#ifndef AUTH_H
#define AUTH_H
#include <string>
#include <vector>
#include "user.h"
using namespace std;
class AuthSystem {
private:
vector<User> users;
public:
AuthSystem();
User* login();
bool validateUser(const string& username, const string& password);
};
#endif

@ -0,0 +1,52 @@
#include "file_manager.h"
#include <fstream>
#include <filesystem>
#include <chrono>
#include <iomanip>
using namespace std;
string FileManager::saveToFile(const vector<string>& questions, const string& username, const string& grade) {
// 创建用户文件夹
filesystem::create_directories(username);
// 生成文件名
auto now = chrono::system_clock::now();
time_t time = chrono::system_clock::to_time_t(now);
tm localTime = *localtime(&time);
stringstream filename;
filename << username << "/"
<< put_time(&localTime, "%Y-%m-%d-%H-%M-%S") << ".txt";
// 写入文件
ofstream file(filename.str());
for (const auto& question : questions) {
file << question << "\n\n";
}
file.close();
return filename.str();
}
bool FileManager::checkDuplicate(const vector<string>& newQuestions, const string& username) {
if (!filesystem::exists(username)) {
return true; // 用户文件夹不存在,肯定没有重复
}
// 检查所有现有文件中的题目
for (const auto& entry : filesystem::directory_iterator(username)) {
ifstream file(entry.path());
string line;
while (getline(file, line)) {
for (const auto& newQuestion : newQuestions) {
if (line.find(newQuestion.substr(3)) != string::npos) {
return false; // 发现重复
}
}
}
}
return true; // 没有重复
}

@ -0,0 +1,15 @@
#ifndef FILE_MANAGER_H
#define FILE_MANAGER_H
#include <vector>
#include <string>
using namespace std;
class FileManager {
public:
string saveToFile(const vector<string>& questions, const string& username, const string& grade);
bool checkDuplicate(const vector<string>& newQuestions, const string& username);
};
#endif

@ -0,0 +1,75 @@
#include <iostream>
#include <string>
#include "auth.h"
#include "question_generator.h"
#include "file_manager.h"
#include "user.h"
#include "utils.h"
using namespace std;
int main() {
AuthSystem auth;
QuestionGenerator generator;
FileManager fileManager;
while (true) {
// 登录验证
User* currentUser = auth.login();
if (currentUser == nullptr) {
continue;
}
// 主循环
while (true) {
cout << "准备生成" << currentUser->getGradeName()
<< "数学题目,请输入生成题目数量(输入-1将退出当前用户重新登录";
string input;
getline(cin, input);
if (input == "-1") {
delete currentUser;
break;
}
// 切换难度检查
if (input.find("切换为") == 0) {
string newGrade = input.substr(9); // 提取"切换为"后面的内容
if (newGrade == "小学" || newGrade == "初中" || newGrade == "高中") {
currentUser->setGrade(newGrade);
cout << "准备生成" << currentUser->getGradeName()
<< "数学题目,请输入生成题目数量:" << endl;
continue;
} else {
cout << "请输入小学、初中和高中三个选项中的一个" << endl;
continue;
}
}
// 生成题目
try {
int count = stoi(input);
if (count >= 10 && count <= 30) {
vector<string> questions = generator.generateQuestions(
currentUser->getGrade(), count, currentUser->getUsername());
// 查重和保存
if (fileManager.checkDuplicate(questions, currentUser->getUsername())) {
string filename = fileManager.saveToFile(
questions, currentUser->getUsername(), currentUser->getGradeName());
cout << "题目已生成并保存到:" << filename << endl;
} else {
cout << "发现重复题目,请重新生成" << endl;
}
} else {
cout << "题目数量应在10-30之间" << endl;
}
} catch (const exception& e) {
cout << "请输入有效的数字" << endl;
}
}
}
return 0;
}

@ -0,0 +1,102 @@
#include "question_generator.h"
#include <random>
#include <sstream>
#include <cmath>
using namespace std;
vector<string> QuestionGenerator::generateQuestions(const string& grade, int count, const string& username) {
vector<string> questions;
for (int i = 1; i <= count; i++) {
string question;
if (grade == "小学") {
question = generatePrimaryQuestion();
} else if (grade == "初中") {
question = generateMiddleSchoolQuestion();
} else if (grade == "高中") {
question = generateHighSchoolQuestion();
}
questions.push_back(to_string(i) + ". " + question);
}
return questions;
}
string QuestionGenerator::generatePrimaryQuestion() {
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<> opCountDist(1, 5);
uniform_int_distribution<> numDist(1, 100);
uniform_int_distribution<> opTypeDist(0, 3); // +, -, *, /
int opCount = opCountDist(gen);
vector<int> numbers;
vector<char> operators;
// 生成数字
for (int i = 0; i <= opCount; i++) {
numbers.push_back(numDist(gen));
}
// 生成运算符
for (int i = 0; i < opCount; i++) {
int opType = opTypeDist(gen);
switch (opType) {
case 0: operators.push_back('+'); break;
case 1: operators.push_back('-'); break;
case 2: operators.push_back('*'); break;
case 3: operators.push_back('/'); break;
}
}
// 构建题目字符串
stringstream ss;
ss << numbers[0];
for (int i = 0; i < opCount; i++) {
ss << " " << operators[i] << " " << numbers[i + 1];
}
ss << " = ";
return ss.str();
}
string QuestionGenerator::generateMiddleSchoolQuestion() {
// 初中题目实现(包含平方和开根号)
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<> choice(0, 1);
if (choice(gen) == 0) {
// 平方题目
uniform_int_distribution<> numDist(1, 20);
int num = numDist(gen);
return to_string(num) + "2 = ";
} else {
// 开根号题目
uniform_int_distribution<> numDist(1, 400);
int num = numDist(gen);
return "" + to_string(num) + " = ";
}
}
string QuestionGenerator::generateHighSchoolQuestion() {
// 高中题目实现(包含三角函数)
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<> trigDist(0, 2);
uniform_int_distribution<> angleDist(0, 360);
int angle = angleDist(gen);
string trigFunc;
switch (trigDist(gen)) {
case 0: trigFunc = "sin"; break;
case 1: trigFunc = "cos"; break;
case 2: trigFunc = "tan"; break;
}
return trigFunc + "(" + to_string(angle) + "°) = ";
}

@ -0,0 +1,19 @@
#ifndef QUESTION_GENERATOR_H
#define QUESTION_GENERATOR_H
#include <vector>
#include <string>
using namespace std;
class QuestionGenerator {
private:
string generatePrimaryQuestion(); // 小学题目
string generateMiddleSchoolQuestion(); // 初中题目
string generateHighSchoolQuestion(); // 高中题目
public:
vector<string> generateQuestions(const string& grade, int count, const string& username);
};
#endif

@ -0,0 +1,20 @@
#include "user.h"
using namespace std;
User::User(const string& uname, const string& pwd, const string& grd)
: username(uname), password(pwd), grade(grd) {}
User::User(const User& other)
: username(other.username), password(other.password), grade(other.grade) {}
string User::getGradeName() const {
if (grade == "小学") return "小学";
if (grade == "初中") return "初中";
if (grade == "高中") return "高中";
return "未知";
}
void User::setGrade(const string& newGrade) {
grade = newGrade;
}

@ -0,0 +1,25 @@
#ifndef USER_H
#define USER_H
#include <string>
using namespace std;
class User {
private:
string username;
string password;
string grade;
public:
User(const string& uname, const string& pwd, const string& grd);
User(const User& other);
string getUsername() const { return username; }
string getPassword() const { return password; }
string getGrade() const { return grade; }
string getGradeName() const;
void setGrade(const string& newGrade);
};
#endif

@ -0,0 +1,12 @@
#ifndef UTILS_H
#define UTILS_H
#include <string>
using namespace std;
// 工具函数声明
string trim(const string& str);
bool isNumber(const string& str);
#endif

@ -0,0 +1,152 @@
[Project]
FileName=软件2301_周禹彤_个人项目.dev
Name=软件2301_周禹彤_个人项目
Type=1
Ver=2
ObjFiles=
Includes=
Libs=
PrivateResource=
ResourceIncludes=
MakeIncludes=
Compiler=
CppCompiler=
Linker=
IsCpp=1
Icon=
ExeOutput=
ObjectOutput=
LogOutput=
LogOutputEnabled=0
OverrideOutput=0
OverrideOutputName=
HostApplication=
UseCustomMakefile=0
CustomMakefile=
CommandLine=
Folders=
IncludeVersionInfo=0
SupportXPThemes=0
CompilerSet=0
CompilerSettings=0000000000000000000000000
UnitCount=10
[VersionInfo]
Major=1
Minor=0
Release=0
Build=0
LanguageID=1033
CharsetID=1252
CompanyName=
FileVersion=
FileDescription=Developed using the Dev-C++ IDE
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=
AutoIncBuildNr=0
SyncProduct=1
[Unit1]
FileName=main.cpp
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit2]
FileName=auth.h
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit3]
FileName=auth.cpp
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit4]
FileName=question_generator.h
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit5]
FileName=question_generator.cpp
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit6]
FileName=file_manager.h
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit7]
FileName=file_manager.cpp
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit8]
FileName=user.h
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit9]
FileName=user.cpp
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit10]
FileName=utils.h
CompileCpp=1
Folder=
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=

@ -0,0 +1,53 @@
[Editors]
Order=0,1,2,3,4,5,6,7,8,9
Focused=0
[Editor_0]
CursorCol=18
CursorRow=6
TopLine=1
LeftChar=1
[Editor_1]
CursorCol=18
CursorRow=6
TopLine=1
LeftChar=1
[Editor_2]
CursorCol=2
CursorRow=43
TopLine=8
LeftChar=1
[Editor_3]
CursorCol=7
CursorRow=19
TopLine=1
LeftChar=1
[Editor_4]
CursorCol=2
CursorRow=102
TopLine=67
LeftChar=1
[Editor_5]
CursorCol=7
CursorRow=15
TopLine=1
LeftChar=1
[Editor_6]
CursorCol=2
CursorRow=52
TopLine=17
LeftChar=1
[Editor_7]
CursorCol=7
CursorRow=25
TopLine=1
LeftChar=1
[Editor_8]
CursorCol=2
CursorRow=20
TopLine=1
LeftChar=1
[Editor_9]
CursorCol=7
CursorRow=12
TopLine=1
LeftChar=1
Loading…
Cancel
Save