考试系统分析报告

写作目的:

上次,我分析了一个ATM 的项目,为了夯实项目基础,写了一个简单的考试系统项目,话不多说,我们开始品。
我把源码放在网盘里,有需要的小伙伴可以自行下载
链接:https://pan.baidu.com/s/1OL3amIvZkztSkpb5gUcVNA
提取码:3b2t

整体脉络:

在这里插入图片描述

开始分析:

EXAM.h

//
// Created by asus on 2020/5/16.
//

#ifndef EXAM_EXAM_H
#define EXAM_EXAM_H
#include "Student.h"
#include "Question.h"
#include "Screen.h"
#include "Keyboard.h"
#include "File.h"
#include "Test_description.h"
#include <string>
#include <fstream>
#include <stdlib.h>
#include <vector>
#include <iostream>
#include <algorithm>
#include <ctime>
#include "QuestionDatabase.h"
#include "StudentsDatabase.h"
using namespace std;
class EXAM
{
public:
    EXAM();
    void run();         //run
    void Time(double);  //the plateform of Time.
    bool state();       //state ,initialization is true.
    void operation();   //begin run.
    void logical_order();
    void random_student();
    void random_question();
private:
    Screen screen;
    Keyboard keyboard;
    File file;
    Test_description testDescription;
    StudentsDatabase studentsdatabase;
    QuestionDatabase questionsdatabase;
    bool istest;
};
#endif //EXAM_EXAM_H

看着很复杂,其实明白了他们的具体用法,一点也不负载,并且很简单(。◕ˇ∀ˇ◕)
EXAM.cpp

//
// Created by asus on 2020/5/16.
//
#include "EXAM.h"
static int a[5];//credit the random of student
static int b[15];//credit the random of question number
enum Menuoption {STUDENT = 1,EXIT };
EXAM::EXAM():istest(true) {}
bool EXAM::state()
{
    return istest;
}

void EXAM :: run()
{
    srand((int)time(0));
    while(true)     //permanence
    {
        operation();   //begin
    }

}

void EXAM::operation()
{
    bool Exit = false;
    while (!Exit)
    {
        testDescription.description();
        int K;
        K = testDescription.platform();
        switch (K)
        {
            case STUDENT:
                logical_order();

                break;
            case EXIT:
                screen.printline("Existing the system...");
                screen.printline("Thanks you, good bye!");
                screen.printline("");
                Exit = true;
                break;
            default:
                screen.printline("Invalid option. Try Again!");
                screen.printline("");
        }
    }
}
void EXAM::logical_order()
{
    random_student();
    random_question();

    int n = 0;  //the limit of question
    int q = 0; //question number 15  (all)
    double start;  //time end
    double end;    //time begin
    double time_;  //credit time
    string Y_N = "";
    string _Y_N = "";
    while (n<5)
    {
        int m = 0;  //the limit of question 3 (personal)
        screen.printline("");
        Student *student_ ;
        student_ = new Student(0,"0")
        student_ = studentsdatabase.getStudent(a[n]);
        student_->diplay_();
        file.file("Id: ");
        file.file(student_->get_id());
        file.file(" Name: ");
        file.file(student_->get_name());
        file.file();
        file.file("Question: ");
        file.file("");
        //begin exam
        screen.printline("press keyboard and Enter to take the test,and Timing start.");
        Y_N = keyboard.inputs();
        start = time(NULL);
        while (m<3)
        {
            Question *question_;
            question_ = new Question(1,"1");
            question_ = questionsdatabase.getquestion(b[q++]);
            question_->display();
            m++;
            screen.printline("Next question to press keyboard:");
            _Y_N = keyboard.inputs();
            while (m == 3)
            {
                screen.printline("Three questions have been reached, and the system will automatically select the next person for you ");
                screen.printline("");
                break;
            }

        }
        end = time(NULL);
        time_  = end - start;

        //the circumstance of students
        screen.printline("Answers situation");
        tudent_[n++].diplay_();
        screen.printline("Complete question :");
        for(int i = q - 3;i < q;i++)
        {
           cout<<b[i]<<" ";
           file.file(b[i]);
           file.file(" ");
        }

        file.file();
        screen.printline("");
        Time(time_);
        screen.printline("");
    }
    screen.printline("End of exam");
    screen.printline("");
}

void EXAM::random_student()
{

    vector <int> temp;
    for(int i = 20201;i<=20205;i++)
    {
        temp.push_back(i);
    }
    random_shuffle(temp.begin(), temp.end());//random id
    //credit id to array;
    for(int i=0; i<temp.size();i++)
    {
        a[i] = temp[i];
    }


}

void EXAM::random_question()
{

    vector <int> temp1;
    for(int i = 1;i<=15;i++)
    {
        temp1.push_back(i);
    }
    random_shuffle(temp1.begin(), temp1.end());//random question
    //credit question to array
    for(int i=0; i<temp1.size();i++)
    {
        b[i] = temp1[i];
    }
}
void EXAM:: Time (double a)
{
    if (a < 60)
    {
        if (a<10)
        {
            cout<<"Total time:  00:0"<<a<<endl;
            file.file("Total time:  00:0");
            file.file(a);
            file.file();
            file.file();
        }

        else
        {
            cout<<"Total time:  00:"<<a<<endl;
            file.file("Total time:  00:");
            file.file(a);
            file.file();
            file.file();
        }

    }
    else if (a < 60 * 60)
    {
        int b ;
        b = int(a/60);
        int c;
        c = a - b * 60;
        cout<<"Total time:  "<<b<<":";
        file.file("Total time:  ");
        if (c == 0)
        {
            cout<<"00"<<endl;
            file.file("00");
            file.file();
            file.file();
        }
    }
}

我们先看run()方法,我们srand((int)time(0));我们先不管,车需一直处在运行中,所以一切都由while(true) 护着,我们继续看operation()

void EXAM::operation()
{
    bool Exit = false;
    while (!Exit)
    {
        testDescription.description();
        int K;
        K = testDescription.platform();
        switch (K)
        {
            case STUDENT:
                logical_order();

                break;
            case EXIT:
                screen.printline("Existing the system...");
                screen.printline("Thanks you, good bye!");
                screen.printline("");
                Exit = true;
                break;
            default:
                screen.printline("Invalid option. Try Again!");
                screen.printline("");
        }
    }
}

考试系统可以考试,也可以退出考试,默认可以考试,bool Exit = false;testDescription.description();这句话是考试须知,不信您看,(这行代码,在Test_description中,所以我把它调出来,方便观看)

//
// Created by asus on 2020/5/17.
//

#include "Test_description.h"

void Test_description::description()
{
    screen.printline("**Welcome to Tianjin Polytechnic**");
    screen.printline("Examination room rules");
    screen.printline("Welcome to take this exam.");
    screen.printline("The order of answer and qusetion is random.");
    screen.printline("Up to 3 questions per person.");
    screen.printline("******************************");
}
int Test_description::platform()
{
    screen.printline("Press (1) to start random roll call, press (2) to exit.");
    return keyboard.inputi();
}
//
// Created by asus on 2020/5/17.
//

#ifndef EXAM_TEST_DESCRIPTION_H
#define EXAM_TEST_DESCRIPTION_H

#include "Screen.h"
#include "Keyboard.h"
class Test_description {
public:
    void description();     //the explaintion of exam
    int platform();    //platform
private:
    Screen screen;
    Keyboard keyboard;
};


#endif //EXAM_TEST_DESCRIPTION_H

这里出现了,screen和keyboard。我们一同引出来,(这里面没有太多操作,所以就把零零碎碎的分析掉)
screen.h

//
// Created by asus on 2020/5/16.
//

#ifndef EXAM_SCREEN_H
#define EXAM_SCREEN_H

#include <vector>
#include <string>
using namespace std;
class Screen
{
public:
    void print(string);
    void printline(string);
};


#endif //EXAM_SCREEN_H

screen.cpp

//
// Created by asus on 2020/5/16.
//

#include "Screen.h"
#include <iostream>
using namespace std;

void Screen::print(string message)
{
    cout<<message;
}
void Screen::printline(string message)
{
    cout<<message<<endl;
}

Keyboard.h

//
// Created by asus on 2020/5/17.
//

#ifndef EXAM_KEYBOARD_H
#define EXAM_KEYBOARD_H

#include <iostream>
#include <string>
using namespace std;
//template <class T>
class Keyboard
{
public:
    int inputi();
    string inputs();
//    template <typename T1>
//    T1 input()
//    {
//        T1 x;
//        cin>>x;
//        return x;
//    }           //在c++17 可以使用
};


#endif //EXAM_KEYBOARD_H

Keyboard.cpp

//
// Created by asus on 2020/5/17.
//

#include "Keyboard.h"

int Keyboard:: inputi()
{
    int  x;
    cin>>x;
    return x;
}
string Keyboard:: inputs()
{
    string x;
    cin>>x;
    return x;
}

有了前面的四段代码,我们对testDescription.description();一目了然,

        int K;
        K = testDescription.platform();
        switch (K)
        {
            case STUDENT:
                logical_order();

                break;
            case EXIT:
                screen.printline("Existing the system...");
                screen.printline("Thanks you, good bye!");
                screen.printline("");
                Exit = true;
                break;
            default:
                screen.printline("Invalid option. Try Again!");
                screen.printline("");
        }

这几行,大概意思是,屏幕上提示你,然后根据自己的意愿,完成对应操作,其中switch配合着enum Menuoption {STUDENT = 1,EXIT };
这里面值得疑惑的就是logical_order();让我们带着期待的目光来一探究竟!

void EXAM::logical_order()
{
    random_student();
    random_question();

    int n = 0;  //the limit of question
    int q = 0; //question number 15  (all)
    double start;  //time end
    double end;    //time begin
    double time_;  //credit time
    string Y_N = "";
    string _Y_N = "";
    while (n<5)
    {
        int m = 0;  //the limit of question 3 (personal)
        screen.printline("");
        Student *student_ ;
        student_ = new Student(1,"a");
        student_ = studentsdatabase.getStudent(a[n]);
        student_->diplay_();
        file.file("Id: ");
        file.file(student_->get_id());
        file.file(" Name: ");
        file.file(student_->get_name());
        file.file();
        file.file("Question: ");
        file.file("");
        //begin exam
        screen.printline("press keyboard and Enter to take the test,and Timing start.");
        Y_N = keyboard.inputs();
        start = time(NULL);
        while (m<3)
        {
            Question *question_;
            question_ = new Question(1,"1");
            question_ = questionsdatabase.getquestion(b[q++]);
            question_->display();
            m++;
            screen.printline("Next question to press keyboard:");
            _Y_N = keyboard.inputs();
            while (m == 3)
            {
                screen.printline("Three questions have been reached, and the system will automatically select the next person for you ");
                screen.printline("");
                break;

            }

        }

        end = time(NULL);
        time_  = end - start;

        //the circumstance of students
        screen.printline("Answers situation");

//        student_[c].diplay();
        student_[n++].diplay_();
        screen.printline("Complete question :");
        for(int i = q - 3;i < q;i++)
        {
           cout<<b[i]<<" ";
           file.file(b[i]);
           file.file(" ");
        }

        file.file();
        screen.printline("");
        Time(time_);
        screen.printline("");
//        delete(student_);
    }
    screen.printline("End of exam");
    screen.printline("");

}

前两句random_student();random_question();这两句有着同样的功能,先看第一句

void EXAM::random_student()
{

    vector <int> temp;
    for(int i = 20201;i<=20205;i++)
    {
        temp.push_back(i);
    }
    random_shuffle(temp.begin(), temp.end());//random id
    //credit id to array;
    for(int i=0; i<temp.size();i++)
    {
        a[i] = temp[i];
    }


}


```cpp
void EXAM::random_question()
{

    vector <int> temp1;
    for(int i = 1;i<=15;i++)
    {
        temp1.push_back(i);
    }
    random_shuffle(temp1.begin(), temp1.end());//random question
    //credit question to array
    for(int i=0; i<temp1.size();i++)
    {
        b[i] = temp1[i];
    }
}

这里实现的原理和random_student是一样的。我们继续向下走

	int n = 0;  //the limit of question
    int q = 0; //question number 15  (all)
    double start;  //time end
    double end;    //time begin
    double time_;  //credit time
    string Y_N = "";
    string _Y_N = "";

这里定义的变量都是为后面服务的,大概意思我们从注释就可以看出。

    while (n<5)
    {
        int m = 0;  //the limit of question 3 (personal)
        screen.printline("");
        Student *student_ ;
        student_ = studentsdatabase.getStudent(a[n]);
        file.file("Id: ");
        file.file(student_->get_id());
        file.file(" Name: ");
        file.file(student_->get_name());
        file.file();
        file.file("Question: ");
        file.file("");
        student_->diplay_();
        //begin exam
        screen.printline("press keyboard and Enter to take the test,and Timing start.");
        Y_N = keyboard.inputs();
        start = time(NULL);
        while (m<3)
        {
            Question *question_;
            question_ = questionsdatabase.getquestion(b[q++]);
            question_->display();
            m++;
            screen.printline("Next question to press keyboard:");
            _Y_N = keyboard.inputs();
            while (m == 3)
            {
                screen.printline("Three questions have been reached, and the system will automatically select the next person for you ");
                screen.printline("");
                break;
            }

        }
        end = time(NULL);
        time_  = end - start;

        //the circumstance of students
        screen.printline("Answers situation");
        student_[n++].diplay();
        screen.printline("Complete question :");
        for(int i = q - 3;i < q;i++)
        {
           cout<<b[i]<<" ";
           file.file(b[i]);
           file.file(" ");
        }

        file.file();
        screen.printline("");
        Time(time_);
        screen.printline("");
    }
    screen.printline("End of exam");
    screen.printline("");

首先一共有5个人,所以while (n<5),然后int m = 0; //the limit of question 3 (personal)
然后我们看

		Student *student_ ;
        student_ = studentsdatabase.getStudent(a[n]);
        student_->diplay_();

这里出现了学生数据库,我们把它调出来,分析一下

//
// Created by asus on 2020/5/20.
//

#ifndef EXAM_STUDENTSDATABASE_H
#define EXAM_STUDENTSDATABASE_H

#include <stdlib.h>
#include "Student.h"
#include <vector>
using namespace std;
class StudentsDatabase {
public:
    StudentsDatabase();
    Student*  getStudent(int);
private:
    vector<Student> students;   //the content of student

};
#endif //EXAM_STUDENTSDATABASE_H
//
// Created by asus on 2020/5/20.
//

#include "StudentsDatabase.h"
StudentsDatabase::StudentsDatabase()
{
    Student student1(20201,"Zhao**");
    Student student2(20202,"Qian**");
    Student student3(20203,"Sun**");
    Student student4(20204,"Li**");
    Student student5(20205,"Zhou**");
    students.push_back(student1);
    students.push_back(student2);
    students.push_back(student3);
    students.push_back(student4);
    students.push_back(student5);
}

Student* StudentsDatabase::getStudent(int _id)
{
    for (size_t index = 0; index < students.size(); ++index) {
        if (students[index].get_id() == _id)
            return &students[index];
    }
    return NULL;
}

在其构造函数存放着学生的基本信息(学号和姓名),里面用到了容器操作,我们再来看

Student* StudentsDatabase::getStudent(int _id)
{
    for (size_t index = 0; index < students.size(); ++index) {
        if (students[index].get_id() == _id)
            return &students[index];
    }
    return NULL;
}

首先将所传入的id进行遍历,匹配出所对应处的id学生对象,将其返回出去。student_->diplay_();将其打印。既然出现学生类,此处将其引出

//
// Created by asus on 2020/5/19.
//

#ifndef EXAM_STUDENT_H
#define EXAM_STUDENT_H

#include <string>
#include "File.h"
#include <iostream>
using namespace std;
class Student {
public:
    Student(int,string);
    int get_id();
    void diplay_();

private:
    int id;
    string name;
    File file;
};
//
// Created by asus on 2020/5/19.
//

#include "Student.h"

Student::Student(int _id = 0, string _name = ""):id(_id),name(_name){}
int Student::get_id()
{
    return this->id;
}
void Student::diplay_()
{
    cout<<"id : "<<this->id<<","<<"name : "<<this->name<<endl;
}

里面存在File类的操作,我们把它引出

//
// Created by asus on 2020/5/22.
//

#ifndef EXAM_FILE_H
#define EXAM_FILE_H

#include <fstream>
#include <string>
#include <iostream>
using namespace std;
class File {
public:
    void file(string);
    void file(int);
    void file();
    void file_();//文件是否打开
};


#endif //EXAM_FILE_H
//
// Created by asus on 2020/5/22.
//

#include "File.h"
void File::file_()
{
    ofstream ofs;
    if(!ofs){
        cout<<"Error open"<<endl;
        exit(-1);
    }
    if(!ofs){
        cout<<"Error open"<<endl;
        exit(-1);
    }
}
void File::file(string a)
{
    ofstream ofs;
    file_();
    ofs.open("EXAM.txt",ios::app);
    ofs<<a;
}
void File::file(int b)
{
    ofstream ofs;
    file_();
    ofs.open("EXAM.txt",ios::app);
    ofs<<b;
}
void File::file()
{
    ofstream ofs;
    file_();
    ofs.open("EXAM.txt",ios::app);
    ofs<<endl;
}

在学生类中,有返回id的方法,和display,display_的方法。为什么要分两个display,因为在文件操作中,利用了函数的重载,可以将字符串和变量的值分别传入,并且在屏幕上打印两次,学生信息(开始考试的时候和总结的时候)。

Y_N = keyboard.inputs();

这行代码就是停顿一下,并且开始计时,start = time(NULL);
time()返回的是从公元1970年1月1日开始到现在的时间。
下面的m<3就是每个人最多三道题,三道题之后自动退出,

			Question *question_;
            question_ = questionsdatabase.getquestion(b[q++]);

这两行代码 和前面的学生和学生库的代码,原理完全一样。

_Y_N = keyboard.inputs();

这句话也是起到停顿作用,根据提示进入下一题,

while (m == 3)
            {
                screen.printline("Three questions have been reached, and the system will automatically select the next person for you ");
                screen.printline("");
                break;
            }

当m = 3 就是答完题了。之后

		end = time(NULL);
        time_  = end - start;

在经过

void EXAM:: Time (double a)
{
    if (a < 60)
    {
        if (a<10)
        {
            cout<<"Total time:  00:0"<<a<<endl;
            file.file("Total time:  00:0");
            file.file(a);
            file.file();
            file.file();
        }

        else
        {
            cout<<"Total time:  00:"<<a<<endl;
            file.file("Total time:  00:");
            file.file(a);
            file.file();
            file.file();
        }

    }
    else if (a < 60 * 60)
    {
        int b ;
        b = int(a/60);
        int c;
        c = a - b * 60;
        cout<<"Total time:  "<<b<<":";
        file.file("Total time:  ");
        if (c == 0)
        {
            cout<<"00"<<endl;
            file.file("00");
            file.file();
            file.file();
        }
    }
}

将具体所用时间,打印并且存放在文件中,

 screen.printline("Answers situation");
        student_[n++].diplay();
        screen.printline("Complete question :");
        for(int i = q - 3;i < q;i++)
        {
           cout<<b[i]<<" ";
           file.file(b[i]);
           file.file(" ");
        }

        file.file();
        screen.printline("");
        Time(time_);
        screen.printline("");
    }
    screen.printline("End of exam");
    screen.printline("");

上面的操作,将题号和时间存放在文件中并且在文件中打印。之后这个项目就完成了。
如果有一些需要改进的,或是需要改进的,欢迎到评论区留言。(◕ᴗ◕✿)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值