湖南大学个人项目互评

作者:胡友缘

/*
...一些注释信息... */ #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; }
  1. 包含了几个头文件,包括feature.huser.h
  2. main() 函数首先初始化一个新的Teacher对象。
  3. 通过UserLogin()函数进行用户登录。如果登录成功,则进入操作界面。
  4. 在操作界面中,用户可以选择生成数学题目的数量。输入“-1”将退出当前用户并重新登录。用户还可以通过输入“切换为XX”来切换题目类型,其中XX可以是小学、初中或高中。
  5. 使用UserControl()函数进行用户控制,进入操作界面。
  6. 在结束时,释放了先前分配的内存。
/* ...注释信息... */

#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_

 

  1. UserLogin(User *user): 用户登录及验证功能。如果登录成功,返回true;如果失败,返回false。
  2. UserControl(User *user, bool &continue_while, char *input): 用户操作界面,这里我们可以进行数学题目的选择和生成。
  3. IfToggle(User *user, bool &continue_while, char *input, char *toggle): 判断并执行账户类型切换操作(例如从小学切换到初中)。如果操作不合法,返回false。
  4. 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_

 

这里定义了两个类:

  1. User类:这是一个虚基类,用于定义用户的基本功能和属性。该类有以下功能:

    • 设置和获取用户名、密码和账号类型。
    • 定义了两个纯虚函数:Login()GetTestPaper(int n),这意味着任何从User类派生的子类都需要实现这两个函数。
  2. 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;
  }
}

优点:

  1. 结构化代码:这个函数有清晰的结构。它先处理目录和文件相关的操作,然后处理与试卷相关的操作。
  2. 资源管理:使用 opendirclosedir,确保目录资源被正确管理。
  3. 时间戳使用:通过 timelocaltime 为文件命名提供了时间戳,这确保了文件名的唯一性。
  4. 链表遍历:代码使用了链表结构来存储和遍历数学问题,这是数据结构中的一个常见模式。
  5. 内存管理:在遍历结束后,使用 delete 释放了链表的内存。

这个函数展示了如何获取、格式化和保存数学试卷。它结合了文件操作、时间管理和链表遍历等多个方面的知识,整体上是一个很好的代码示例。

一些缺点:

有一些代码没有很好的遵守谷歌编程规范。

 

 
 
posted @ 2023-09-21 21:53  Songjf-ttk  阅读(202)  评论(0)    收藏  举报