合并 #1

Merged
hnu202326010401 merged 11 commits from develop into main 4 months ago

@ -0,0 +1,3 @@
windows平台
无参数设置
编码GBK

@ -0,0 +1,24 @@
#include"account.h"
Authenticator::Authenticator(){
users = {
User("张三1","123","小学"),
User("张三2","123","小学"),
User("张三3","123","小学"),
User("李四1","123","初中"),
User("李四2","123","初中"),
User("李四3","123","初中"),
User("王五1","123","高中"),
User("王五2","123","高中"),
User("王五3","123","高中"),
};
}
User* Authenticator::authenticate(const std::string& username,const std::string& password){
for(User& user : users){
if(user.UserName == username&&user.Password == password){
return &user;
}
}
return nullptr;
}

@ -0,0 +1,15 @@
#ifndef ACCOUNT_H
#define ACCOUNT_H
#include"case.h"
#include<vector>
class Authenticator{
private:
std::vector<User> users;
public:
User* authenticate(const std::string& username,const std::string& password);
Authenticator();
};
#endif

@ -0,0 +1,25 @@
#ifndef CASE_H
#define CASE_H
#include<string>
class User{
public:
std::string UserName;
std::string Password;
std::string UserType;
User(const std::string& uname,const std::string& pwd,const std::string& type)
:UserName(uname),Password(pwd),UserType(type){}
};
class Question{
public:
int id;
std::string content;
Question(int ID,const std::string& cont)
:id(ID),content(cont){}
};
#endif

@ -0,0 +1,67 @@
#include"filemanage.h"
#include"tool.h"
#include<fstream>
#include<direct.h>
#include<iostream>
#include<dirent.h>
Filemanage::Filemanage(const std::string&dir):baseDir(dir){
createDir(baseDir);
}
void Filemanage::createDir(const std::string& path){
_mkdir(path.c_str());
}
std::string Filemanage::getUserFolder(const std::string& username){
std::string userFolder = baseDir + "/" + username;
createDir(userFolder);
return userFolder;
}
std::string Filemanage::saveQuestions(const std::string& username,const std::vector<Question> questions){
std::string userFolder = getUserFolder(username);
std::string filename = tool::getCurrentTime() + ".txt";
std::string filepath = userFolder + "/" + filename;
std::ofstream userpath(filepath);
if(!userpath.is_open()){
std::cout<<"ÎÞ·¨´´½¨Îļþ"<<filepath<<std::endl;
}
for(const Question question:questions){
userpath<<question.id<<"."<<question.content<<std::endl<<std::endl;
}
userpath.close();
return filepath;
}
std::set<std::string> Filemanage::getQuestions(const std::string&username){
std::set<std::string>productedQuestion;
std::string userFolder = getUserFolder(username);
DIR* dirstream = opendir(userFolder.c_str());
struct dirent* dir;
while((dir = readdir(dirstream)) != NULL){
std::string filename = dir->d_name;
if(filename.length() > 4&&filename.substr(filename.length() - 4) == ".txt"){
std::string filepath = userFolder + "/" + filename;
std::ifstream userpath;
userpath.open(filepath);
if(userpath.is_open()){
std::string OneQuestion;
while(getline(userpath,OneQuestion)){
OneQuestion = tool::EreaseEmpty(OneQuestion);
if(!OneQuestion.empty()&&OneQuestion.find('.') != std::string::npos){
int dotnum = OneQuestion.find('.');
OneQuestion = OneQuestion.substr(dotnum + 1,OneQuestion.size() - dotnum - 1);
productedQuestion.insert(OneQuestion);
}
}
}
userpath.close();
}
}
closedir(dirstream);
return productedQuestion;
}

@ -0,0 +1,20 @@
#ifndef FILEMANAGE_H
#define FILEMANAGE_H
#include"case.h"
#include<string>
#include<set>
#include<vector>
class Filemanage{
private:
std::string baseDir;
std::string getUserFolder(const std::string& username);
void createDir(const std::string& path);
public:
Filemanage(const std::string& dir = "examquestions");
std::set<std::string>getQuestions(const std::string&username);
std::string saveQuestions(const std::string& username,const std::vector<Question> questions);
};
#endif

@ -0,0 +1,133 @@
#include<iostream>
#include<regex>
#include"account.h"
#include"case.h"
#include"filemanage.h"
#include"question_product.h"
#include"tool.h"
class ExamSystem{
private:
Authenticator authenticator;
Filemanage fileManage;
QuestionProduction questionProduction;
User* currentUser;
bool IsUser = false;
void SystemLogin();
void SystemProductQuestions();
void handleSwitchType(const std::string& newtype);
void ProductQuestion(int num);
public:
void systemRun();
};
void ExamSystem::systemRun(){
std::cout<<"====欢迎使用中小学卷子自动生成系统===="<<std::endl;
while(1){
if(!IsUser){
SystemLogin();
}else{
SystemProductQuestions();
}
}
};
void ExamSystem::SystemLogin(){
std::cout<<"请输入账号 密码登录:";
std::string Input;
getline(std::cin,Input);
Input = tool::EreaseEmpty(Input);
if(Input.empty()){
return ;
}
std::vector<std::string> tokens = tool::split(Input);
if(tokens.size() != 2){
std::cout<<std::endl<<"请输入正确的用户名、密码:";
return ;
}
currentUser = authenticator.authenticate(tokens[0],tokens[1]);
if(currentUser == nullptr){
std::cout<<std::endl<<"请输入正确的用户名、密码:";
return ;
}else{
std::cout<<std::endl<<"准备生成"<<currentUser->UserType<<"数学题目,请输入生成题目数量(输入-1将退出当前用户重新登录)";
IsUser = true;
}
}
void ExamSystem::SystemProductQuestions(){
std::string Input;
getline(std::cin,Input);
if(Input == "-1"){
currentUser = nullptr;
IsUser = false;
return ;
}
std::regex switchPattern("切换为(\\S+)");
std::smatch match;
if(std::regex_match(Input,match,switchPattern)){
std::string newType = match[1].str();
handleSwitchType(newType);
return ;
}
if(!tool::isNumber(Input)){
std::cout<<"请输入有效的数字10~30"<<std::endl;
return ;
}
int count = stoi(Input);
if(count < 10||count >30){
std::cout<<"题目数量范围应为10~30"<<std::endl;
return ;
}
ProductQuestion(count);
}
void ExamSystem::handleSwitchType(const std::string& newtype){
std::vector<std::string> Levels = {"小学","初中","高中"};
bool isLevel = false;
for(std::string Level:Levels){
if(Level == newtype){
isLevel = true;
}
}
if(!isLevel){
std::cout<<"请输入小学、初中和高中三个选项中的一个"<<std::endl;
return ;
}
currentUser->UserType = newtype;
std::cout<<"准备生成"<<currentUser->UserType<<"数学题目,请输入生成题目数量:";
}
void ExamSystem::ProductQuestion(int num){
std::cout<<"正在生成"<<num<<""<<currentUser->UserType<<"数学题目请耐心等待ovo"<<std::endl;
std::set<std::string> hadquestion = fileManage.getQuestions(currentUser->UserName);
std::vector<Question> newquestions;
int id = 1;
while(id <= num){
Question tempQuestion = questionProduction.questionProduction(id,currentUser->UserType);
int QuestionNum = hadquestion.size();
hadquestion.insert(tempQuestion.content);
if(QuestionNum != hadquestion.size()){
newquestions.push_back(tempQuestion);
id++;
}
}
std::string filename = fileManage.saveQuestions(currentUser->UserName,newquestions);
std::cout<<"试卷已成功生成并保存"<<std::endl;
std::cout<<"成功生成"<<num<<""<<currentUser->UserType<<"数学题目,保存至 "<<filename<<" 文件内"<<std::endl;
}
int main(){
ExamSystem system;
system.systemRun();
return 0;
}

@ -0,0 +1,115 @@
#include"question_product.h"
#include<cstdlib>
#include<ctime>
int QuestionProduction::randnum(int min,int max){
int num = (rand()%(max - min + 1)) + min;
return num;
}
Question QuestionProduction::questionProduction(int questionId,const std::string& usertype){
int operationnum = randnum(1,5);
std::vector<int> operations;
for(int i = 0;i < operationnum;i++){
operations.push_back(randnum(1,100));
}
if(usertype == "Сѧ"){
return primaryProduction(questionId,operations);
}else if(usertype == "³õÖÐ"){
return juniorProduction(questionId,operations);
}else if(usertype == "¸ßÖÐ"){
return seniorProduction(questionId,operations);
}
}
Question QuestionProduction::primaryProduction(int questionId,const std::vector<int>&operation){
if(operation.size() == 1){
std::string expression = std::to_string(operation[0]);
return Question(questionId,expression);
}
std::string expression = std::to_string(operation[0]);
for(int i = 1;i < operation.size();i++){
std::string op = primaryWay[randnum(0,primaryWay.size() - 1)];
bool ifbracket = randnum(0,1);
if(ifbracket){
expression = "(" + expression + " " + op + " " + std::to_string(operation[i]) + ")";
}else{
expression = expression + " " + op + " " + std::to_string(operation[i]);
}
}
return Question(questionId,expression);
}
Question QuestionProduction::juniorProduction(int questionId,const std::vector<int>&operation){
std::string expression = std::to_string(operation[0]);
bool ifSpecialop = false;
for(int i = 1;i < operation.size();i++){
if(randnum(0,1) == 1){
if(randnum(0,1) == 1){
expression = "¡Ì" + expression;
}else{
expression = "(" + expression + ")?";
}
ifSpecialop = true;
}
std::string op = primaryWay[randnum(0,primaryWay.size() - 1)];
bool ifbracket = randnum(0,1);
if(ifbracket){
expression = "(" + expression + " " + op + " " + std::to_string(operation[i]) + ")";
}else{
expression = expression + " " + op + " " + std::to_string(operation[i]);
}
}
if(!ifSpecialop){
if(randnum(0,1) == 1){
expression = "¡Ì" + expression;
}else{
expression = "(" + expression + ")?";
}
}
return Question(questionId,expression);
}
Question QuestionProduction::seniorProduction(int questionId,const std::vector<int>&operation){
std::string expression = std::to_string(operation[0]);
bool ifTrigonometric = false;
for(int i = 1;i < operation.size();i++){
if(randnum(0,1)){
std::vector<std::string>trigFuns = {"sin","cos","tan"};
std::string trigFun = trigFuns[randnum(0,2)];
expression = trigFun + "(" + expression + ")";
ifTrigonometric = true;
}else if(randnum(0,2) == 0){
if(randnum(0,1) == 1){
expression = "¡Ì" + expression;
}else{
expression = "(" + expression + ")?";
}
}
std::string op = primaryWay[randnum(0,primaryWay.size() - 1)];
bool ifbracket = randnum(0,1);
if(ifbracket){
expression = "(" + expression + " " + op + " " + std::to_string(operation[i]) + ")";
}else{
expression = expression + " " + op + " " + std::to_string(operation[i]);
}
}
if(!ifTrigonometric){
std::vector<std::string>trigFuns = {"sin","cos","tan"};
std::string trigFun = trigFuns[randnum(0,2)];
expression = trigFun + "(" + expression + ")";
}
return Question(questionId,expression);
}

@ -0,0 +1,23 @@
#ifndef QUESTION_PRODUCT_H
#define QUESTION_PRODUCT_H
#include"case.h"
#include<vector>
#include<string>
class QuestionProduction{
private:
std::vector<std::string>primaryWay = {"+","-","*","/"};
std::vector<std::string>juniorWay = {"+","-","*","/","²",""};
std::vector<std::string>seniorWay = {"+","-","*","/","²","","sin","cos","tan"};
Question primaryProduction(int questionId,const std::vector<int>&operation);
Question juniorProduction(int questionId,const std::vector<int>&operation);
Question seniorProduction(int questionId,const std::vector<int>&operation);
public:
Question questionProduction(int questionId,const std::string& usertype);
int randnum(int min,int max);
};
#endif

@ -0,0 +1,58 @@
#include"tool.h"
#include<sstream>
#include<ctime>
std::vector<std::string>tool::split(const std::string& str){
std::istringstream iss(str);
std::vector<std::string> tokens;
std::string token;
std::istringstream tokenStream(str);
while(std::getline(tokenStream,token,' ')){
tokens.push_back(token);
}
return tokens;
}
bool tool::isNumber(const std::string& str){
if(str.empty()){
return false;
}
int start = 0;
if(str[0] == '-'){
if(str.size() == 1){
return false;
}
start = 1;
}
for(int i = start;i < str.size();i++){
if(!isdigit(str[i])){
return false;
}
}
return true;
}
std::string tool::getCurrentTime(){
time_t now = time(0);
tm* ltm = localtime(&now);
char buffer[80];
strftime(buffer,80,"%Y-%m-%d-%H-%M-%S",ltm);
std::string nowTime = buffer;
return nowTime;
}
std::string tool::EreaseEmpty(const std::string& question){
int start = question.find_first_not_of("\t\n\r");
int end = question.find_last_not_of("\t\n\r");
if(start == std::string::npos||end == std::string::npos){
return "";
}
return question.substr(start,end - start + 1);
}

@ -0,0 +1,17 @@
#ifndef TOOL_H
#define TOOL_H
#include<string>
#include<vector>
namespace tool{
std::vector<std::string>split(const std::string& str);
bool isNumber(const std::string& str);
std::string getCurrentTime();
std::string EreaseEmpty(const std::string& question);
}
#endif
Loading…
Cancel
Save