首发于 课程设计
基于C++实现(控制台)简易学生学籍管理系统【100010146】

基于C++实现(控制台)简易学生学籍管理系统【100010146】

学生学籍管理系统

1 系统需求分析

1.1 设计目的

(1)体验面向对象的编程思想,了解封装,继承,多态的基本思想。

(2)熟练运用文件操作,函数定义与使用,头文件引入,数组,类,循环结构,选择结构,判断结构等基本工具进行架构。

(3)体会开发流程,明白各个开发环节的意义以及作用。

1.2 需求分析

(1)学生学籍管理系统实现用户基本对数据操作的功能有:学生信息的录入、浏览、分类、排序、查询、统计、删除、修改、清空功能。还要求可以读写学生信息文件,以及实现退出功能。为与用户交互,功能需要以菜单方式工作,供用户选择

1.3 用户需求

(1)学生学籍信息读写文件功能;

(2)学生学籍信息录入功能;

(3)学生学籍信息浏览、分类、排序功能;

(4)学生学籍信息查询、统计功能;

(5)学生学籍信息删除功能;

(6)学生学籍信息修改功能;

(7)学生学籍信息清空功能;

2 系统总体设计

针对一般学生学籍管理系统的需求,通过对学生信息内容的分析,设计如图 2.1 所示的数据结构:

2.1 数据结构



图 2.1 数据结构

2.2 系统功能模块设计

根据实际需求和整体设计,可以将系统功能分为以下模块:



图 2.2 系统功能结构图

通过在需求阶段对系统的总体功能的要求,我们得到了这个学生学籍管理系统的总体功能结构,它应包括以下几大基本功能:

(1)菜单功能实现:系统显示菜单界面与用户形成交互。

(2)退出功能:用户输入指定数字实现退出功能。

(3)添加学生:选择功能后,系统给出提示,进行操作添加。

(4)显示学生:将文件中所有的学生信息显示出来。

(5)删除学生:按照学号删除学生信息。

(6)查找学生:根据学号查找学生信息。

(7)修改学生信息:按照学号找到学生后对学生信息进行修改。

(8)按学号排序:根据学号对学生进行排序。

(9)按年级分类查看:按照年级显示学生信息。

(10)清空数据:清空文件里所有学生数据。

3 系统详细设计

3.1 设计思想

(1)将管理操作类封装:对信息操作的函数、记录学生人数的变量、存储学生信息的指针数组进行封装。类内成员包括:记录人数的变量、学生的指针数组,构造函数、显示菜单、添加学生、退出程序、保存文件、文件是否为空的标志、统计人数、初始化、显示学生、删除学生、判断学生是否存在、查找学生、修改学生、按学号排序、清空数据、按年级分类显示、析构函数 。

(2)将学生信息类封装:对学生信息,包括类内自带的显示信息,年级的成员函数封装。类内包括成员:显示个人信息的成员函数、获取年级名称的成员函数、学号、姓名、性别、年级编号、班级、年龄等属性。

3.2 程序内部结构



图 3.2 程序内部结构图

3.3 设计流程

(1)创建学生类

先创建学生类作为父类,然后定义各种成员属性,类内包含显示年级函数和显示自身信息函数。子类继承学生抽象类,并重写父类中的重虚函数 分别继承出,大一,大二,大三,大四,四个子类。

(2)创建管理类

管理类负责的内容如下:提供与用户的沟通菜单界面、实现对职工增删改查的操作、数组数据与文件的读写交互。

(3)菜单功能实现

在 StudentManager.h 中定义 ShowMenu()函数在 StudentManager.cpp 中实现显示菜单功能,便于与用户交互,利用序号将所有功能显示出来,便于用户选择以及,进行后期的使用。在 main 函数中为管理操作的函数提供接口,创建实例对象,调用对象内成员函数。

(4)退出功能

在 StudentManager.h 中定义 Exit_System();函数在 StudentManager.cpp 中实现函数功能,利用 exit(0);实现程序的退出操作。

(5)添加学生

在 StudentManager.h 中添加属性以及成员函数。根据学生的人数加上添加后的人数,开辟一块新的空间记录数据。系统整体利用指针数组实现数据的临时保存,最终与文件的操作配合使用,使数据转存到文件中。在 StudentManager.cpp 中构造函数中初始化。在 StudentManager.cpp 中实现成员函数。

(6)保存文件

读取当前的指针数组,然后将数组元素存入文件中。

(7)初始化学生

在初始化学生之前,要判断学生文件状态,分为三种情况: 第一次使用文件未创建。 文件存在,但是为空文件。 文件和数据正常存在.

首先在 StudentManager.h 中添加标志文件是否为空的标志,若为空文件,或者文件不存在,则该 bool 类型的值返回 true,修改 StudentManager.cpp 中的构造函数代码,如果文件不存在,则初始化文件,文件不存在,或者为空的情况下,判断文件是否为空的标志都为真,成功添加学生信息后更改文件不为空,初始化文件,初始化 Student 类型的指针数组,将 Student 类型的地址存到 Student 中,在 StudentManager.cpp 中实现。

(8)显示学生

基本思想就是遍历输出,按照需求可以按照不同的条件显示。

(9)删除学生

删除学生之前判断其是否存在,如果为空或者不存在,返回-1,如果存在,返回其下标,在 StudentManager.cpp 中实现,根据成员属性匹配的到数组的下标,便于后续索引类型的操作进行删除,实现按照学号删除。

(10)查找学生

按照学生编号,按照学生姓名,通过遍历加判断的方式查找。

(11)修改学生信息

按照编号对职工信息保存修改,利用 IsExist 函数获取学生数组元素下标,然后对应进行修改,记录保存。

(12)按学号排序

排序采用冒泡排序,前后两两比较,根据排序要求进行交换元素位置,达到排序目的。

(13)按年级分类查看

遍历数组,匹配相应年级相应代码,然后输出每个年级下面的学生分类。

(14)清空数据

首先确认是否清空,然后打开文件,打开模式 ios::trunc 就是如果存在删除文件并重新创建,关闭文件,判断,如果指针数组不为空,那么将里面的指针释放干净,成员个数更新为零,将指针数组置为空,更新文件为空的标志。

3.4 开发流程



图 3.4 开发流程图

4 编码实现

4.1 main 函数

#include<iostream>
# include"StudentManage.h"
# include"Grade.h"
# include"Student.h"
using namespace std;
int main()
    system("color B1");
    StudentManager stu;
    int chioce;
    while (true)
        //显示菜单
        stu.Show_Menu();
        cout << "请输入您的选择:";
        cin >> chioce;
        switch (chioce)
        case 0:stu.Exit_System();//退出系统
            break;
        case 1:stu.Add_Student();//录入学生
            break;
        case 2:stu.ShowStudent();//显示学籍
            break;
        case 3:stu.DeleteStudent();//删除学生
            break;
        case 4:stu.ModStudent();//修改学生
            break;
        case 5:stu.FindStudent();//查找学生
            break;
        case 6:stu.SortStudent();//学生排序
            break;
        case 7:stu.ClassifyStudent();//分类显示
            break;
        case 8:stu.CleanStudent();//清空系统
            break;
        default://
            system("cls");
            break;
        system("pause");
    return 0;

4.2 student.h 头文件实现

#pragma once
# include<iostream>
using namespace std;
# include<string>
class Student;
typedef class Student
public:
    virtual void Show_Info() = 0;//显示个人信息
    virtual string Get_Grade() = 0;//获取年级名称
    int m_id;//学号
    string m_name;//姓名
    string m_sex;//性别
    int  m_grade;//所在年级编号
    string m_class;//班级
    int m_age;//年龄
}STU, * PSTU;

4.3 Grade.h 头文件实现

#pragma once
# include"Student.h"
typedef class Grade01 :public Student//大一学生类,继承学生类
public:
    void Show_Info();//显示个人信息
    string Get_Grade();//获取年级名称
    Grade01(int id, string name, int grade, string sex, string m_class, int m_age);//构造函数
}Grade01, * PGrade01;
typedef class Grade02 :public Student//大二学生类,继承学生类
public:
    void Show_Info();//显示个人信息
    string Get_Grade();//获取年级名称
    Grade02(int id, string name, int grade, string sex, string m_class, int m_age);//构造函数
}Grade02, * PGrade02;
typedef class Grade03 :public Student//大三学生类,继承学生类
public:
    void Show_Info();//显示个人信息
    string Get_Grade();//获取年级名称
    Grade03(int id, string name, int grade, string sex, string m_class, int m_age);//构造函数
}Grade03, * PGrade03;
typedef class Grade04 :public Student//大一学生类,继承学生类
public:
    void Show_Info();//显示个人信息
    string Get_Grade();//获取年级名称
    Grade04(int id, string name, int grade, string sex, string m_class, int m_age);//构造函数
}Grade04, * PGrade04;

4.4 Grade.cpp 源文件实现

#pragma once
# include"Student.h"
typedef class Grade01 :public Student//大一学生类,继承学生类
public:
    void Show_Info();//显示个人信息
    string Get_Grade();//获取年级名称
    Grade01(int id, string name, int grade, string sex, string m_class, int m_age);//构造函数
}Grade01, * PGrade01;
typedef class Grade02 :public Student//大二学生类,继承学生类
public:
    void Show_Info();//显示个人信息
    string Get_Grade();//获取年级名称
    Grade02(int id, string name, int grade, string sex, string m_class, int m_age);//构造函数
}Grade02, * PGrade02;
typedef class Grade03 :public Student//大三学生类,继承学生类
public:
    void Show_Info();//显示个人信息
    string Get_Grade();//获取年级名称
    Grade03(int id, string name, int grade, string sex, string m_class, int m_age);//构造函数
}Grade03, * PGrade03;
typedef class Grade04 :public Student//大一学生类,继承学生类
public:
    void Show_Info();//显示个人信息
    string Get_Grade();//获取年级名称
    Grade04(int id, string name, int grade, string sex, string m_class, int m_age);//构造函数
}Grade04, * PGrade04;

4.5 studentManage.h 源文件实现

#pragma once
# include<iostream>
using namespace std;
# include<string>
# include<fstream>//操作文件
# include"Student.h"
# define FILENAME "empFile.txt"//给文件名宏定义,便于后期维护
class StudentManager
public:
    //记录人数
    int Student_Num;
    //学生数组的指针
    PSTU* Student_Array;//指针数组用来存Student* 的数组(Student*)* Student_Array;
    //构造函数
    StudentManager();
    //显示菜单
    void Show_Menu();
    //添加学生
    void Add_Student();
    //退出程序
    void Save();
    //保存文件
    void Exit_System();
    //文件是否为空的标志
    bool FileIsEmpty;
    //统计人数
    int get_StudentNum();
    //初始化
    void InitStudent();
    //显示学生
    void ShowStudent();
    //删除学生
    void DeleteStudent();
    //判断职工是否存在,若存在返回位置,若不存在返回-1
    int IsExist(int id);
    //查找学生
    void FindStudent();
    //修改学生
    void ModStudent();
    //按学号排序
    void SortStudent();
    //清空数据
    void CleanStudent();
    //按年级分类显示
    void ClassifyStudent();
    //析构函数
    ~StudentManager();

4.6 StudentManage.cpp 源文件实现

//头文件
# include"StudentManage.h"
# include"Grade.h"
//构造函数
StudentManager::StudentManager()//
    ifstream ifs;//创建流对象
    ifs.open(FILENAME, ios::in);//为读文件打开文件
    //文件不存在情况
    if (!ifs.is_open())
        //cout << "文件不存在" << endl;
        this->Student_Num = 0;//初始化人数为零
        this->FileIsEmpty = true;//标志文件为空
        this->Student_Array = NULL;//指针数组为空
        ifs.close();//关闭文件
        return;//函数结束标志
    //文件存在,但是没有记录
    char ch;
    ifs >> ch;
    if (ifs.eof())
        //cout << "文件为空" << endl;
        this->Student_Num = 0;
        this->FileIsEmpty = true;
        this->Student_Array = NULL;//指针数组为空
        ifs.close();//关闭文件
        return;//函数结束标志
    int num = this->get_StudentNum();
    //cout << "学生个数为:" << num << endl;
    this->Student_Num = num;
    //根据学生数创建数组
    this->Student_Array = new PSTU[this->Student_Num];
    this->InitStudent();
}//构造函数
//显示菜单
void StudentManager::Show_Menu()
    cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
    cout << "~~~~~~~~~~~~~~~~学生学籍管理系统~~~~~~~~~~~~~~~~" << endl;
    cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
    cout << "******************(0)退出系统*****************" << endl;
    cout << "******************(1)录入学生*****************" << endl;
    cout << "******************(2)显示学籍*****************" << endl;
    cout << "******************(3)删除学生*****************" << endl;
    cout << "******************(4)修改学生*****************" << endl;
    cout << "******************(5)查找学生*****************" << endl;
    cout << "******************(6)学生排序*****************" << endl;
    cout << "******************(7)分类显示*****************" << endl;
    cout << "******************(8)清空系统*****************" << endl;
    cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
    cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
void StudentManager::Exit_System()
    cout << "欢迎下次使用" << endl;
    system("pause");
    exit(0);
void StudentManager::Add_Student()
    cout << "请输入添加学生数量" << endl;
    int addnum;
    cin >> addnum;
    if (addnum > 0)
        //计算新空间大小
        int newsize = this->Student_Num + addnum;
        //开辟空间
        PSTU* newspace = new PSTU[newsize];
        //将源空间的内容存放到新空间下
        if (this->Student_Array != NULL)
            for (int i = 0; i < this->Student_Num; i++)
                newspace[i] = this->Student_Array[i];
        //输入新数据
        for (int i = 0; i < addnum; i++)
            int id;
            string name;
            int select;
            string sex;
            string m_class;
            int m_age;
            cout << "请输入第" << i + 1 << "个学生学号" << endl;
            cin >> id;
            cout << "请输入第" << i + 1 << "个学生姓名" << endl;
            cin >> name;
            cout << "请输入第" << i + 1 << "个学生年级编号" << endl;
            cout << "1、大一" << endl;
            cout << "2、大二" << endl;
            cout << "3、大三" << endl;
            cout << "4、大四" << endl;
            cin >> select;
            cout << "请输入第" << i + 1 << "个学生性别" << endl;
            cin >> sex;
            cout << "请输入第" << i + 1 << "个学生班级" << endl;
            cin >> m_class;
            cout << "请输入第" << i + 1 << "个学生年龄" << endl;
            cin >> m_age;
            PSTU student = NULL;
            switch (select)
            case 1://大一
                student = new Grade01(id, name, 1, sex, m_class, m_age);
                break;
            case 2://大2
                student = new Grade02(id, name, 2, sex, m_class, m_age);
                break;
            case 3://大3
                student = new Grade03(id, name, 3, sex, m_class, m_age);
                break;
            case 4://大4
                student = new Grade04(id, name, 4, sex, m_class, m_age);
                break;
            default:
                break;
            newspace[this->Student_Num + i] = student;
        //释放原有空间
        delete[]this->Student_Array;
        //更新空间指向
        this->Student_Array = newspace;
        //更新学生个数
        this->Student_Num = newsize;
        //更改为空标志
        this->FileIsEmpty = false;
        cout << "添加成功" << addnum << "个学生" << endl;
        this->Save();//保存文件
    else {
        cout << "输入有误" << endl;
    system("pause");
    system("cls");
//保存文件
void StudentManager::Save()
    ofstream ofs;
    ofs.open(FILENAME, ios::out);//以写文件的方式打开文件
    for (int i = 0; i < this->Student_Num; i++)
        ofs << this->Student_Array[i]->m_id << " "
            << this->Student_Array[i]->m_name << " "
            << this->Student_Array[i]->m_grade << " "
            << this->Student_Array[i]->m_sex << " "
            << this->Student_Array[i]->m_class << " "
            << this->Student_Array[i]->m_age << " " << endl;
    ofs.close();
//获取学生个数
int StudentManager::get_StudentNum()
    ifstream ifs;
    ifs.open(FILENAME, ios::in);
    int id;
    string name;
    int grade;
    string sex;
    string m_class;
    int m_age;
    int num = 0;
    while (ifs >> id && ifs >> name && ifs >> grade && ifs >> sex && ifs >> m_class && ifs >> m_age)
        //记录人数
        num++;
    ifs.close();
    return num;
//初始化
void StudentManager::InitStudent()
    ifstream ifs;
    ifs.open(FILENAME, ios::in);
    int id;
    string name;
    int grade;
    int index = 0;
    string sex;
    string m_class;
    int m_age;
    while (ifs >> id && ifs >> name && ifs >> grade && ifs >> sex && ifs >> m_class && ifs >> m_age)
        PSTU student = NULL;//根据年级创建PSTU的对象
        if (id == 1)
            student = new Grade01(id, name, grade, sex, m_class, m_age);
        else if (id == 2)
            student = new Grade02(id, name, grade, sex, m_class, m_age);
        else if (id == 3)
            student = new Grade03(id, name, grade, sex, m_class, m_age);
            student = new Grade04(id, name, grade, sex, m_class, m_age);
        //存放在数组中
        this->Student_Array[index] = student;
        index++;
void StudentManager::ShowStudent()
    if (this->FileIsEmpty)
        cout << "文件为空或者不存在" << endl;
        for (int i = 0; i < this->Student_Num; i++)
            //利用多态调用接口
            this->Student_Array[i]->Show_Info();
    system("pause");
    system("cls");
void StudentManager::DeleteStudent()
    if (this->FileIsEmpty)
        cout << "文件不存在或者记录为空" << endl;
        cout << "请输入要删除的学生学号" << endl;
        int id = 0;
        cin >> id;
        int index = this->IsExist(id);
        if (index != -1)
            for (int i = index; i < this->Student_Num - 1; i++)
                this->Student_Array[i] = this->Student_Array[i + 1];
            this->Student_Num--;
            this->Save();//删除后同步数据到文件
            cout << "删除成功" << endl;
            cout << "删除失败,未找到该学生" << endl;
    system("pause");
    system("cls");
void StudentManager::FindStudent()
    if (this->FileIsEmpty)
        cout << "文件不存在或者记录为空!" << endl;
        cout << "请输入查找的方式:" << endl;
        cout << "1、按编号查找" << endl;
        cout << "2、按姓名查找" << endl;
        int select = 0;
        cin >> select;
        if (select == 1)//按照学号查找
            int id;
            cout << "请输入查找的学号" << endl;
            cin >> id;
            int ret = this->IsExist(id);
            if (ret != -1)
                cout << "查找成功,该学生信息如下" << endl;
                this->Student_Array[ret]->Show_Info();
                cout << "查找失败,查无此人" << endl;
        else if (select == 2)//按姓名查找
            string name;
            cout << "请输入查找的姓名" << endl;
            cin >> name;
            bool flag = false;//查找到的标志
            for (int i = 0; i < this->Student_Num; i++)
                if (this->Student_Array[i]->m_name == name)
                    cout << "查找成功,信息如下" << endl;
                    flag = true;
                    this->Student_Array[i]->Show_Info();
            if (flag == false)
                cout << "查找失败,查无此人!!" << endl;
            cout << "输入选项有误" << endl;
    system("pause");
    system("cls");
void StudentManager::ModStudent()
    if (this->FileIsEmpty)
        cout << "文件不存在,或记录为空" << endl;
        cout << "请输入要修改的学生学号" << endl;
        int id;
        cin >> id;
        int ret = this->IsExist(id);
        if (ret != -1)
            delete this->Student_Array[ret];
            int newid = 0;
            string newname = "";
            int select = 0;
            string newsex;
            string newclass;
            int newage;
            cout << "查到" << id << "号学生,请输入新学号" << endl;
            cin >> newid;
            cout << "请输入新姓名" << endl;
            cin >> newname;
            cout << "请输入年级" << endl;
            cout << "1、大一" << endl;
            cout << "2、大二" << endl;
            cout << "3、大三" << endl;
            cout << "4、大四" << endl;
            cin >> select;
            cout << "请输入班级" << endl;
            cin >> newclass;
            cout << "请输入年龄" << endl;
            cin >> newage;
            Student* student = NULL;
            switch (select)
            case 1://大一
                student = new Grade01(newid, newname, 1, newsex, newclass, newage);
                break;
            case 2://大2
                student = new Grade02(newid, newname, 2, newsex, newclass, newage);
                break;
            case 3://大3
                student = new Grade03(newid, newname, 3, newsex, newclass, newage);
                break;
            case 4://大4
                student = new Grade04(newid, newname, 4, newsex, newclass, newage);
                break;
            default:
                break;
            //更新数据到数组中
            this->Student_Array[ret] = student;
            cout << "修改成功" << endl;
            //保存文件
            this->Save();
            cout << "修改失败,查无此人" << endl;
        system("pause");
        system("cls");
//判断是否存在
int StudentManager::IsExist(int id)
    int index = -1;
    for (int i = 0; i < this->Student_Num; i++)
        if (this->Student_Array[i]->m_id == id)
            index = i;
            break;
    return index;
void StudentManager::SortStudent()
    if (this->FileIsEmpty)
        cout << "文件不存在或者记录为空" << endl;
        system("pause");
        system("cls");
        cout << "请选择排序方式: " << endl;
        cout << "1、按学号进行升序" << endl;
        cout << "2、按学号进行降序" << endl;
        int select = 0;
        cin >> select;
        for (int i = 0; i < this->Student_Num; i++)
            int minOrmax = i;
            for (int j = i + 1; j < this->Student_Num; j++)
                if (select == 1)
                    if (this->Student_Array[minOrmax]->m_id > this->Student_Array[j]->m_id)
                        minOrmax = j;
                    if (this->Student_Array[minOrmax]->m_id < this->Student_Array[j]->m_id)
                        minOrmax = j;
            if (i != minOrmax)
                Student* temp = this->Student_Array[i];
                this->Student_Array[i] = this->Student_Array[minOrmax];
                this->Student_Array[minOrmax] = temp;
        cout << "排序成功" << endl;
        this->Save();
        system("pause");
        system("cls");
void StudentManager::CleanStudent()
    cout << "确认清空?" << endl;
    cout << "1、确认" << endl;
    cout << "2、返回" << endl;
    int select = 0;
    cin >> select;
    if (select == 1)
        //打开模式ios::trunc如果存在就删除文件并重新创建
        ofstream ofs(FILENAME, ios::trunc);
        ofs.close();
        if (this->Student_Array != NULL)
            for (int i = 0; i < this->Student_Num; i++)
                if (this->Student_Array[i] != NULL)
                    delete this->Student_Array[i];
            this->Student_Num = 0;
            delete[] this->Student_Array;
            this->Student_Array = NULL;
            this->FileIsEmpty = true;
        cout << "清空成功" << endl;
    system("pause");
    system("cls");
//分类显示
void StudentManager::ClassifyStudent()
    cout << "大一:" << endl;
    for (int i = 0; i < this->Student_Num; i++)
        if (this->Student_Array[i]->m_grade == 1)
            this->Student_Array[i]->Show_Info();
    cout << endl;
    cout << "大二:" << endl;
    for (int i = 0; i < this->Student_Num; i++)
        if (this->Student_Array[i]->m_grade == 2)
            this->Student_Array[i]->Show_Info();
    cout << endl;
    cout << "大三:" << endl;
    for (int i = 0; i < this->Student_Num; i++)
        if (this->Student_Array[i]->m_grade == 3)
            this->Student_Array[i]->Show_Info();
    cout << endl;
    cout << "大四:" << endl;
    for (int i = 0; i < this->Student_Num; i++)
        if (this->Student_Array[i]->m_grade == 4)
            this->Student_Array[i]->Show_Info();
    system("pause");
    system("cls");
//析构函数
StudentManager::~StudentManager()