diff --git a/doc/说明文档.md b/doc/说明文档.md new file mode 100644 index 0000000..abd88c6 --- /dev/null +++ b/doc/说明文档.md @@ -0,0 +1,3 @@ +windows平台 +无参数设置 +编码GBK \ No newline at end of file diff --git a/src/account.cpp b/src/account.cpp new file mode 100644 index 0000000..b1ee00b --- /dev/null +++ b/src/account.cpp @@ -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; +} \ No newline at end of file diff --git a/src/account.h b/src/account.h new file mode 100644 index 0000000..586bfe6 --- /dev/null +++ b/src/account.h @@ -0,0 +1,15 @@ +#ifndef ACCOUNT_H +#define ACCOUNT_H + +#include"case.h" +#include + +class Authenticator{ + private: + std::vector users; + public: + User* authenticate(const std::string& username,const std::string& password); + Authenticator(); +}; + +#endif \ No newline at end of file diff --git a/src/case.h b/src/case.h new file mode 100644 index 0000000..6ee5bcb --- /dev/null +++ b/src/case.h @@ -0,0 +1,25 @@ +#ifndef CASE_H +#define CASE_H + +#include + +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 \ No newline at end of file diff --git a/src/filemanage.cpp b/src/filemanage.cpp new file mode 100644 index 0000000..5cc7ed2 --- /dev/null +++ b/src/filemanage.cpp @@ -0,0 +1,67 @@ +#include"filemanage.h" +#include"tool.h" +#include +#include +#include +#include + +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 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<<"޷ļ"< Filemanage::getQuestions(const std::string&username){ + std::setproductedQuestion; + 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; +} diff --git a/src/filemanage.h b/src/filemanage.h new file mode 100644 index 0000000..935acc9 --- /dev/null +++ b/src/filemanage.h @@ -0,0 +1,20 @@ +#ifndef FILEMANAGE_H +#define FILEMANAGE_H + +#include"case.h" +#include +#include +#include + +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::setgetQuestions(const std::string&username); + std::string saveQuestions(const std::string& username,const std::vector questions); +}; + +#endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..b52d390 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,133 @@ +#include +#include +#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<<"====ӭʹСѧԶϵͳ===="< tokens = tool::split(Input); + if(tokens.size() != 2){ + std::cout<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"<30){ + std::cout<<"ĿΧӦΪ10~30"< Levels = {"Сѧ","",""}; + bool isLevel = false; + + for(std::string Level:Levels){ + if(Level == newtype){ + isLevel = true; + } + } + + if(!isLevel){ + std::cout<<"Сѧк͸ѡеһ"<UserType = newtype; + std::cout<<"׼"<UserType<<"ѧĿĿ"; +} + +void ExamSystem::ProductQuestion(int num){ + std::cout<<""<UserType<<"ѧĿĵȴovo"< hadquestion = fileManage.getQuestions(currentUser->UserName); + std::vector 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<<"Ծѳɹɲ"<UserType<<"ѧĿ "< +#include + +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 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&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&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&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::vectortrigFuns = {"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::vectortrigFuns = {"sin","cos","tan"}; + std::string trigFun = trigFuns[randnum(0,2)]; + expression = trigFun + "(" + expression + ")"; + } + + return Question(questionId,expression); +} diff --git a/src/question_product.h b/src/question_product.h new file mode 100644 index 0000000..0b8aed3 --- /dev/null +++ b/src/question_product.h @@ -0,0 +1,23 @@ +#ifndef QUESTION_PRODUCT_H +#define QUESTION_PRODUCT_H + +#include"case.h" +#include +#include + +class QuestionProduction{ + private: + std::vectorprimaryWay = {"+","-","*","/"}; + std::vectorjuniorWay = {"+","-","*","/","²","√"}; + std::vectorseniorWay = {"+","-","*","/","²","√","sin","cos","tan"}; + + Question primaryProduction(int questionId,const std::vector&operation); + Question juniorProduction(int questionId,const std::vector&operation); + Question seniorProduction(int questionId,const std::vector&operation); + public: + Question questionProduction(int questionId,const std::string& usertype); + int randnum(int min,int max); +}; + + +#endif \ No newline at end of file diff --git a/src/tool.cpp b/src/tool.cpp new file mode 100644 index 0000000..2659168 --- /dev/null +++ b/src/tool.cpp @@ -0,0 +1,58 @@ +#include"tool.h" +#include +#include + + +std::vectortool::split(const std::string& str){ + std::istringstream iss(str); + std::vector 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); +} \ No newline at end of file diff --git a/src/tool.h b/src/tool.h new file mode 100644 index 0000000..9555959 --- /dev/null +++ b/src/tool.h @@ -0,0 +1,17 @@ +#ifndef TOOL_H +#define TOOL_H + +#include +#include + +namespace tool{ + std::vectorsplit(const std::string& str); + + bool isNumber(const std::string& str); + + std::string getCurrentTime(); + + std::string EreaseEmpty(const std::string& question); +} + +#endif \ No newline at end of file