作者:胡友缘
/* ...一些注释信息... */ #include "feature.h" #include "user.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> int main() { srand(time(0)); // srand根据时间生成rand参数,实现伪随机 User *user = new Teacher(); bool continue_while = 0; // 判断是否处于操作界面执行操作 if(UserLogin(user)) // 登录成功,准备进入操作界面 continue_while = 1; char *input = new char[16]; // 存储输入 while(continue_while) { printf("准备生成%s数学题目, 请输入生成题目数量(输入-1将退出当前用户, 重新登录) \n", user->get_account_type()); printf("题目数量的有效输入范围是“10-30” (含10,30)\n"); printf("如果用户需要切换类型选项, 命令行输入“切换为XX”, XX为小学、初中和高中三个选项中的一个\n"); scanf("%s", input); UserControl(user, continue_while, input); // 进入操作界面 } printf("成功退出程序, 感谢使用中小学数学卷子自动生成程序\n"); delete user; delete input; return 0; }
- 包含了几个头文件,包括
feature.h
和user.h
。 main()
函数首先初始化一个新的Teacher
对象。- 通过
UserLogin()
函数进行用户登录。如果登录成功,则进入操作界面。 - 在操作界面中,用户可以选择生成数学题目的数量。输入“-1”将退出当前用户并重新登录。用户还可以通过输入“切换为XX”来切换题目类型,其中XX可以是小学、初中或高中。
- 使用
UserControl()
函数进行用户控制,进入操作界面。 - 在结束时,释放了先前分配的内存。
/* ...注释信息... */ #ifndef PERSONAL_PROJECT_FEATURE_H_ #define PERSONAL_PROJECT_FEATURE_H_ #include "user.h" // 进行用户登录及验证,登录成功返回true,登录失败返回false bool UserLogin(User *user); // 用户的操作界面 void UserControl(User *user, bool &continue_while, char *input); // 判断并执行切换账号类型的操作,如果操作不合法返回false bool IfToggle(User *user, bool &continue_while, char *input, char *toggle); // 判断并执行试卷生成操作,如果操作不合法返回false bool IfDigit(User *user, bool &continue_while, char *input); #endif //PERSONAL_PROJECT_FEATURE_H_
UserLogin(User *user)
: 用户登录及验证功能。如果登录成功,返回true;如果失败,返回false。UserControl(User *user, bool &continue_while, char *input)
: 用户操作界面,这里我们可以进行数学题目的选择和生成。IfToggle(User *user, bool &continue_while, char *input, char *toggle)
: 判断并执行账户类型切换操作(例如从小学切换到初中)。如果操作不合法,返回false。IfDigit(User *user, bool &continue_while, char *input)
: 判断并执行试卷生成操作。如果操作不合法,返回false。
/* ...注释信息... */ #ifndef PERSONAL_PROJECT_USER_H_ #define PERSONAL_PROJECT_USER_H_ #include "math_problem.h" // User作为虚拟类,实现保存并获取用户信息。 // 能够执行登录操作以及获取并保存数学试卷 class User { public: User(); ~User(); void set_username(char *username); void set_password(char *password); void set_account_type(char *account_type); char* get_username(); char* get_password(); char* get_account_type(); virtual bool Login() = 0; virtual void GetTestPaper(int n) = 0; protected: char *username_; // 用户名 char *password_; // 账号 char *account_type_; // 账号类型 }; // Teacher通过public继承User类 // 能够实现查重功能,以及获取问题,生成试卷 class Teacher: public User { public: Teacher(); ~Teacher(); bool Login(); MathProblem *GetMathProblem(int n); bool CheckProblem(char *problem); bool CheckProblem2(MathProblem *head, MathProblem *last); bool CompleProblem(char *problem, char *cproblem); bool Comple2Problem(char *problem, int place1, char *cproblem, int place2); void GetTestPaper(int n); }; #endif //PERSONAL_PROJECT_USER_H_
这里定义了两个类:
-
User类:这是一个虚基类,用于定义用户的基本功能和属性。该类有以下功能:
- 设置和获取用户名、密码和账号类型。
- 定义了两个纯虚函数:
Login()
和GetTestPaper(int n)
,这意味着任何从User类派生的子类都需要实现这两个函数。
-
Teacher类:这是User类的一个子类,实现了更多的功能:
Login()
: 登录功能。GetMathProblem(int n)
: 获取数学问题。CheckProblem(char *problem)
: 查重功能。CheckProblem2(MathProblem *head, MathProblem *last)
: 另一个查重功能。CompleProblem(char *problem, char *cproblem)
和Comple2Problem(char *problem, int place1, char *cproblem, int place2)
: 完善问题的功能。GetTestPaper(int n)
: 生成试卷功能。
基于这些信息,我们可以得出以下结论:
User
类为基本用户提供了一个框架,而Teacher
类为教师用户提供了特定的功能。- 教师用户可以登录、获取数学问题、检查问题是否重复、完善问题以及生成试卷。
void Teacher::GetTestPaper(int n) { MathProblem *head = GetMathProblem(n); // 获取题目,以链表存储 MathProblem *now = head; DIR *dir = opendir(username_); if(dir == NULL) // 判断是否存在以用户名命名的文件,没有则创建 mkdir(username_, 0755); else closedir(dir); time_t timep; time(&timep); // 获取从1970至今过了多少秒,存入time_t类型的timep struct tm *t = localtime(&timep); char *filepath = new char[64]; sprintf(filepath, "%s/%d-%d-%d-%d-%d-%d.txt", username_, 1900 + t->tm_year, 1+t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); // 获取相对路径 ofstream ofile; ofile.open(filepath, ios::out); char *sign_problem = new char[64]; // 存储具有一定格式的题目 for(int i = 1; now->GetNext() != NULL && now != NULL; ++i) { // 遍历链表 memset(sign_problem, '\0', sizeof(sign_problem)); sprintf(sign_problem, "%2d: %s\n", i, now->GetNext()->GetProblem()); // 以一定格式保存题目 ofile << sign_problem; // 将题目存入文件 now = now->GetNext(); delete head; head = now; } }
优点:
- 结构化代码:这个函数有清晰的结构。它先处理目录和文件相关的操作,然后处理与试卷相关的操作。
- 资源管理:使用
opendir
和closedir
,确保目录资源被正确管理。 - 时间戳使用:通过
time
和localtime
为文件命名提供了时间戳,这确保了文件名的唯一性。 - 链表遍历:代码使用了链表结构来存储和遍历数学问题,这是数据结构中的一个常见模式。
- 内存管理:在遍历结束后,使用
delete
释放了链表的内存。
这个函数展示了如何获取、格式化和保存数学试卷。它结合了文件操作、时间管理和链表遍历等多个方面的知识,整体上是一个很好的代码示例。
一些缺点:
有一些代码没有很好的遵守谷歌编程规范。
标签:char,个人,int,湖南大学,互评,while,bool,User,user From: https://www.cnblogs.com/Songjf-ttk/p/17721062.html