C++大作业——学生选课系统优化版

news2024/11/15 20:06:05

C++大作业——学生选课系统优化版

  • 前言
  • 1.学生类和课程类的实现
  • 2.输入输出流重载的实现
  • 3.增删改查的实现
  • 4.多级菜单的实现
  • 5.选课和退选的实现
  • 5.完整代码

前言


本文是对本人之前写过的一个学生选课系统的优化,整体上的逻辑是和我上一篇博客一样的(链接在此:https://blog.csdn.net/weixin_73870552/article/details/135298985?spm=1001.2014.3001.5501)。本文将具体介绍优化的部分,而不对基本的实现做过多阐述。


1.学生类和课程类的实现


课程类:

class Course
{
	// 输入输出流重载
    friend ostream& operator<<(ostream& out, const Course& c);
    friend fstream& operator<<(fstream& fout, const Course& c);
    // friend istream& operator>>(istream& in, Course& c);        这个重载不好实现,因为要查重
    friend fstream& operator>>(fstream& fin, Course& c);

    friend ostream& operator<<(ostream& out, const Student& s);

public:
	// 构造函数初始化
    Course()
        : _id("None")
        , _name("None")
        , _type(0)
        , _hour(0)
        , _credir(0)
        , _count(0)
    {}

	// 相关接口
    const string c_id() { return _id; }                   // 编号的接口
    const string c_name() { return _name; }               // 名字的接口
    int& c_count() { return _count; }                     // 选课人数的接口
    const bool c_type() { return _type; }                 // 类型接口

	// 文件操作
    void Write(vector<Course>& cour, int n) {}		// 向文件写入数据
    int Read(vector<Course>& cour) {}				// 从文件读取数据

    void Add(vector<Course>& cour) {}				// 增
    void Delete(vector<Course>& cour) {}			// 删
    void Modify(vector<Course>& cour) {}			// 改
    void Lookup(vector<Course>& cour) {}			// 查
    void Show(vector<Course>& cour) {}				// 展示所有信息

private:
    string _id;         // 编号
    string _name;       // 课程名
    bool _type;         // 课程类型,1必修,0选修
    int _hour;          // 学时
    int _credir;        // 学分
    int _count;         // 选课人数
};

1.这个课程类的成员变量中记录了课程的基本信息,其中编号和课程名,这种有字符串属性的数据,我使用了string来存储。方便后续直接使用==!=进行字符串的比较。

2.写了构造函数用来初始化数据。

3.将对课程的操作都写成成员函数,封装起来。后续的操作函数使用涉及到匿名对象,不了解的同学可以看下我之前的博客,这里就不再过多赘述了。

4.设计了一些接口,以便可以在类外访问私有成员变量。其中只有选课人数的接口是没有const修饰的,因为要在类外对其进行修改。

5.声明了输入输出流的重载,用来简化代码。学生类的输出流重载也要在课程类中友元声明一下,因为后续要在这个重载函数中访问课程的一些私有变量,且在这个重载函数中接口会失效。

学生类:

class Student
{
	// 输入输出流重载
    friend ostream& operator<<(ostream& out, const Student& s);
    friend fstream& operator<<(fstream& fout, const Student& s);
    // friend istream& operator>>(istream& in, Student& s);        这个重载不好实现,因为要查重
    friend fstream& operator>>(fstream& fin, Student& s);
public:
    Student()
        : _id("None")                       // 学号
        , _class("None")                    // 班级
        , _name("None")                     // 姓名
        , _num_compulsory(0)                
        , _num_elective(0)
    {}

    void Write(vector<Student>& stu, int n) {}
    int Read(vector<Student>& stu) {}

    void Add(vector<Student>& stu) {}
    void Delete(vector<Student>& stu) {}
    void Modify(vector<Student>& stu) {}
    void Lookup(vector<Student>& stu) {}
    void Show(vector<Student>& stu) {}
    void Select(vector<Course>& cour, vector<Student>& stu) {}		// 选课
    void Deselect(vector<Course>& cour, vector<Student>& stu) {}	// 退选

private:
    string _id;                                 // 学号
    string _class;                              // 班级
    string _name;                               // 名字
    Course _cour_compulsory[SIZE_COMP];         // 必修课信息
    Course _cour_elective[SIZE_ELECT];          // 选修课信息
    int _num_compulsory;                        // 已选必修课数量
    int _num_elective;                          // 已选选修课数量
};

1.学生类的成员变量记录了学生的基本信息。其中,课程的信息我用两个数组存了起来,SIZE_COMPSIZE_ELECT是两个宏,分别对应学生所能选择的必修课和选修课最大数量。

2.学生相关的操作函数作为成员函数,写在Studnet类中,相比课程类多了选课和退选的模块。

3.写了构造函数来初始化数据。

4.声明了输入输出流重载,简化代码。


2.输入输出流重载的实现


课程类的输入输出重载:

ostream& operator<<(ostream& out, const Course& c)
{
    out << c._id   << "\t" << c._name   << "\t" << (c._type ? "必修" : "选修") << "\t"
        << c._hour << "\t" << c._credir << "\t" << c._count;
    return out;
}

fstream& operator<<(fstream& fout, const Course& c)
{
    fout << c._id   << "\t" << c._name   << "\t" << c._type << "\t"
         << c._hour << "\t" << c._credir << "\t" << c._count;
    return fout;
}

fstream& operator>>(fstream& fin, Course& c)
{
    fin >> c._id   >> c._name   >> c._type
        >> c._hour >> c._credir >> c._count;
    return fin;
}

要写一个io流的输出重载,还要写一个文件流的输入输出重载。由于课程类在输入信息时还需要判断课程的编号是否重复,输入流重载略显复杂,还不如直接输入,所以这里就不再实现了。

学生类的输入输出重载:

ostream& operator<<(ostream& out, const Student& s)
{
    out << s._id << "\t" << s._class << "\t" << s._name << "\t";
   for (int i = 0; i < SIZE_COMP; i++)
       out << s._cour_compulsory[i]._name << " ";
   out << "\t";
   for (int i = 0; i < SIZE_ELECT; i++)
       out << s._cour_elective[i]._name << " ";
    return out;
}

fstream& operator<<(fstream& fout, const Student& s)
{
    fout << s._id << "\t" << s._class << "\t" << s._name << "\t";
    for (int i = 0; i < SIZE_COMP; i++)
        fout << s._cour_compulsory[i] << "\t";
    for (int i = 0; i < SIZE_ELECT; i++)
        fout << s._cour_elective[i] << "\t";
    fout << s._num_compulsory << "\t" << s._num_elective;
    return fout;
}

fstream& operator>>(fstream& fin, Student& s)
{
    fin >> s._id >> s._class >> s._name;
    for (int i = 0; i < SIZE_COMP; i++)
        fin >> s._cour_compulsory[i];
    for (int i = 0; i < SIZE_ELECT; i++)
        fin >> s._cour_elective[i];
    fin >> s._num_compulsory >> s._num_elective;
    return fin;
}

学生类的io流输入和课程类同理,要判断学号是否重复,所以这里不再实现重载。应注意,学生类的io流输出重载中,课程信息只输出课程名;学生类的文件流输入输出重载中,复用了课程类的文件输入输出重载。


3.增删改查的实现


实现增删查改,需要借助两个全局的动态数组。vector<Course> courvector<Student> stu

课程类:

class Course
{
    friend ostream& operator<<(ostream& out, const Course& c);
    friend fstream& operator<<(fstream& fout, const Course& c);
    // friend istream& operator>>(istream& in, Course& c);        这个重载不好实现,因为要查重
    friend fstream& operator>>(fstream& fin, Course& c);

    friend ostream& operator<<(ostream& out, const Student& s);

public:
    Course()
        : _id("None")
        , _name("None")
        , _type(0)
        , _hour(0)
        , _credir(0)
        , _count(0)
    {}

    const string c_id() { return _id; }                   // 编号的接口
    const string c_name() { return _name; }               // 名字的接口
    int& c_count() { return _count; }                     // 选课人数的接口
    const bool c_type() { return _type; }                 // 类型接口


    void Write(vector<Course>& cour, int n)
    {
        fstream myfile;
        myfile.open("course.txt", ios::out | ios::binary);
        if (!myfile)
        {
            cout << "course.txt can't open." << endl;
            abort();
        }

        myfile << n << endl << endl;
        for (int i = 0; i < n; i++)
            myfile << cour[i] << endl;

        myfile.close();
    }

    int Read(vector<Course>& cour)
    {
        cour.clear();
        fstream myfile;
        myfile.open("course.txt", ios::in | ios::binary);
        if (!myfile)
        {
            cout << "course.txt can't open." << endl;
            abort();
        }

        int n;
        myfile.seekg(0);
        myfile >> n;

        Course temp;
        for (int i = 0; i < n; i++)
        {
            myfile >> temp;
            cour.push_back(temp);
        }

        myfile.close();
        return n;
    }

    void Add(vector<Course>& cour)
    {
        system("cls");
        int n = Read(cour);
        char sign = '0';
        Course temp;

        cout << "============ 增加课程信息 ============" << endl;
        while (sign != 'n' && sign != 'N')
        {
        loop:
            cout << "ID: ";
            cin >> temp._id;

            // 查重
            int c = 0;
            while (c < n)
            {
                c++;
                if (temp._id == cour[n - c]._id)
                {
                    cout << "编号重复,请重新输入。" << endl;
                    goto loop;
                }
            }

            cout << "课程名: ";
            cin >> temp._name;
            cout << "课程类型(1必修,0选修): ";
            cin >> temp._type;
            cout << "学时: ";
            cin >> temp._hour;
            cout << "学分: ";
            cin >> temp._credir;
            
            n++;

            cour.push_back(temp);

            cout << "是否继续添加(y 或 n)";
            cin >> sign;
        }
        // 保存进文件
        Write(cour, n);
    }

    void Delete(vector<Course>& cour)
    {
        system("cls");
        int n = Read(cour);
        int i = 0;
        string id;

        cout << "============ 删除课程 ============" << endl;
        cout << "请输入需要删除课程的编号: ";
        cin >> id;

        // 检查有没有这个课程
        while (i < n && id != cour[i]._id)
            i++;

        if (i == n)
        {
            cout << "没找到该课程。" << endl;
            system("pause");
            return;
        }
        else
        {
            if (cour[i]._count)
            {
                cout << "所选人数不为零,请联系所有学生退选后,再删除该课程。" << endl;
                system("pause");
                return;
            }
        }

        for (int j = i; j < n - 1; j++)
            cour[j] = cour[j + 1];              // 编译器自动生成的赋值运算符重载

        // 保存
        char sign;
        cout << "是否保存(y 或 n): ";
        cin >> sign;
        if (sign != 'n' && sign != 'N')
        {
            cour.erase(cour.end() - 1);
            Write(cour, n - 1);
            cout << "============ 删除成功 ============" << endl;
            system("pause");
        }
    }

    void Modify(vector<Course>& cour)
    {
        system("cls");
        int n = Read(cour);
        string id;
        int i = 0;

        cout << "============ 修改课程信息 ============" << endl;
        cout << "请输入你想修改的课程id: ";
        cin >> id;

        // 看有没有这个课程
        cin >> id;
        while (i < n && id != cour[i]._id)
            i++;

        if (i == n)
        {
            cout << "没有找到该课程。" << endl;
            system("pause");
            return;
        }
        else
        {
            if (cour[i]._count)
            {
                cout << "所选人数不为零,请联系所有学生退选后,再修改课程信息。" << endl;
                system("pause");
                return;
            }
        }

        cout << "-------------------------------------------------" << endl;
        cout << "编号" << "\t" << "课程名" << "\t" << "类型"     << "\t"
             << "学时" << "\t" << "学分"   << "\t" << "选课人数" << endl;
        cout << cour[i] << endl;
        cout << "-------------------------------------------------" << endl;

        cout << "请重新输入课程信息。" << endl;
        cout << "课程名: ";
        cin >> cour[i]._name;
        cout << "课程类型(1必修,0选修): ";
        cin >> cour[i]._type;
        cout << "学时: ";
        cin >> cour[i]._hour;
        cout << "学分: ";
        cin >> cour[i]._credir;

        // 保存
        char sign;
        cout << "是否保存修改(y 或 n): ";
        cin >> sign;
        if (sign != 'n' && sign != 'N')
        {
            Write(cour, n);
            cout << "============ 修改成功 ============" << endl;
            system("pause");
        }
    }

    void Lookup(vector<Course>& cour)
    {
        system("cls");
        int n = Read(cour);
        int i = 0;
        string id;
        
        cout << "============ 查找课程 ============" << endl;
        cout << "请输入要查找课程的编号: ";
        cin >> id;

        // 检查是否存在
        while (i < n && id != cour[i]._id)
            i++;

        if (i == n)
        {
            cout << "没有找到该课程。" << endl;
        }
        else
        {
            cout << "-------------------------------------------------" << endl;
            cout << "编号" << "\t" << "课程名" << "\t" << "类型"     << "\t"
                 << "学时" << "\t" << "学分"   << "\t" << "选课人数" << endl;
            cout << "-------------------------------------------------" << endl;
            cout << cour[i] << endl;
        }

        system("pause");
    }

    void Show(vector<Course>& cour)
    {
        system("cls");
        int n = Read(cour);

        cout << "============ 展示所有课程信息 ============" << endl;
        cout << "-------------------------------------------------" << endl;
        cout << "编号" << "\t" << "课程名" << "\t" << "类型"     << "\t"
             << "学时" << "\t" << "学分"   << "\t" << "选课人数" << endl;
        cout << "-------------------------------------------------" << endl;
        for (int i = 0; i < n; i++)
            cout << cour[i] << endl;

        system("pause");
    }

private:
    string _id;         // 编号
    string _name;       // 课程名
    bool _type;         // 课程类型,1必修,0选修
    int _hour;          // 学时
    int _credir;        // 学分
    int _count;         // 选课人数
};

学生类:

class Student
{
    friend ostream& operator<<(ostream& out, const Student& s);
    friend fstream& operator<<(fstream& fout, const Student& s);
    // friend istream& operator>>(istream& in, Student& s);        这个重载不好实现,因为要查重
    friend fstream& operator>>(fstream& fin, Student& s);
public:
    Student()
        : _id("None")                       // 学号
        , _class("None")                    // 班级
        , _name("None")                     // 姓名
        , _num_compulsory(0)                
        , _num_elective(0)
    {}

    void Write(vector<Student>& stu, int n)
    {
        fstream myfile;
        myfile.open("student.txt", ios::out | ios::binary);
        if (!myfile)
        {
            cout << "student.txt can't open." << endl;
            abort();
        }

        myfile << n << endl << endl;
        for (int i = 0; i < n; i++)
            myfile << stu[i] << endl;

        myfile.close();
    }

    int Read(vector<Student>& stu)
    {
        stu.clear();
        fstream myfile;
        myfile.open("student.txt", ios::in | ios::binary);
        if (!myfile)
        {
            cout << "student.txt can't open." << endl;
            abort();
        }

        int n;
        myfile.seekg(0);
        myfile >> n;

        Student temp;

        for (int i = 0; i < n; i++)
        {
            myfile >> temp;
            stu.push_back(temp);
        }

        myfile.close();
        return n;
    }

    void Add(vector<Student>& stu)
    {
        system("cls");
        int n = Read(stu);
        char sign = '0';
        Student temp;

        cout << "============ 添加学生 ============" << endl;
        while (sign != 'n' && sign != 'N')
        {
        loop:
            cout << "学号: ";
            cin >> temp._id;

            // 检查重复
            int c = 0;
            while (c < n)
            {
                c++;
                if (temp._id == stu[n - c]._id)
                {
                    cout << "学号重复,请重新输入。" << endl;
                    goto loop;
                }
            }

            cout << "班级: ";
            cin >> temp._class;
            cout << "姓名: ";
            cin >> temp._name;
            n++;

            stu.push_back(temp);

            cout << "是否继续添加(y 或 n): ";
            cin >> sign;
        }

        Write(stu, n);
    }

    void Delete(vector<Student>& stu)
    {
        system("cls");
        int n = Read(stu);
        int m = Course().Read(cour);                    // 课程数量
        int i = 0;
        string id;

        cout << "============ 删除学生 =============" << endl;
        cout << "请输入要删除学生的学号: ";
        cin >> id;

        while (i < n && id != stu[i]._id)
            i++;

        if (i == n)
        {
            cout << "没有找到该学生。" << endl;
            system("pause");
            return;
        }

        // 找到该学生所选的全部课程,并让这些课程的选课人数-1
        if (stu[i]._num_compulsory)
        {
            while (stu[i]._num_compulsory > 0)
            {
                stu[i]._num_compulsory--;

                int c = 0;
                while (c < m)
                {
                    if (stu[i]._cour_compulsory[stu[i]._num_compulsory].c_id() == cour[c].c_id())
                    {
                        cour[c].c_count()--;
                        break;
                    }
                    c++;
                }
            }
        }
        else if (stu[i]._num_elective)
        {
            while (stu[i]._num_elective > 0)
            {
                stu[i]._num_elective--;

                int c = 0;
                while (c < m)
                {
                    if (stu[i]._cour_elective[stu[i]._num_elective].c_id() == cour[c].c_id())
                    {
                        cour[c].c_count()--;
                        break;
                    }
                    c++;
                }
            }
        }

        for (int j = i; j < n - 1; j++)
            stu[j] = stu[j + 1];

        // 保存
        char sign;
        cout << "请确定是否删除(y 或 n): ";
        cin >> sign;
        if (sign != 'n' && sign != 'N')
        {
            stu.erase(stu.end() - 1);
            Write(stu, n - 1);
            Course().Write(cour, m);
            cout << "============ 删除成功 ============" << endl;
            system("pause");
        }
    }

    void Modify(vector<Student>& stu)
    {
        system("cls");
        int n = Read(stu);
        string id;
        int i = 0;

        cout << "============ 修改学生信息 ===========" << endl;
        cout << "请输入你想修改学生的学号: ";
        cin >> id;

        while (i < n && id != stu[i]._id)
            i++;

        if (i == n)
        {
            cout << "找不到该学生。" << endl;
            system("pause");
            return;
        }

        cout << "-------------------------------------------------------" << endl;
        cout << "学号: " << stu[i]._id    << endl;
        cout << "班级: " << stu[i]._class << endl;
        cout << "姓名: " << stu[i]._name  << endl;
        cout << "-------------------------------------------------------" << endl;

        cout << "请重新输入学生信息。" << endl;
        cout << "班级: ";
        cin >> stu[i]._class;
        cout << "姓名: ";
        cin >> stu[i]._name;

        // 保存
        char sign;
        cout << "是否保存修改(y 或 n): ";
        cin >> sign;
        if (sign != 'n' && sign != 'N')
        {
            cout << "修改成功。" << endl;
            Write(stu, n);
            system("pause");
        }
    }

    void Lookup(vector<Student>& stu)
    {
        system("cls");
        int n = Read(stu);
        Course().Read(cour);
        int i = 0;
        string id;

        cout << "============== 查找学生 ==============" << endl;
        cout << "请输入要查找学生的学号: ";
        cin >> id;

        while (i < n && id != stu[i]._id)
            i++;

        if (i == n)
        {
            cout << "找不到该学生。" << endl;
        }
        else
        {
            cout << stu[i] << endl;
        }

        system("pause");
    }

    void Show(vector<Student>& stu)
    {
        system("cls");
        int n = Read(stu);

        cout << "=============================== 展示所有学生信息 ==============================" << endl;
        cout << "学号" << "\t" << "班级" << "\t" << "姓名" << "\t" << "必修课" << "\t" << "选修课" << endl;
        cout << "-------------------------------------------------------------------------------" << endl;
        for (int i = 0; i < n; i++)
            cout << stu[i] << endl;

        system("pause");
    }

private:
    string _id;                                 // 学号
    string _class;                              // 班级
    string _name;                               // 名字
    Course _cour_compulsory[SIZE_COMP];         // 必修课信息
    Course _cour_elective[SIZE_ELECT];          // 选修课信息
    int _num_compulsory;                        // 已选必修课数量
    int _num_elective;                          // 已选选修课数量
};

可以发现,在查找和展示所有的函数中,我使用了输出流重载,让代码的可读性更高,也减少了代码量。

需要注意,和老版本不同,我没有再定义初始化文件的函数Input。所以这需要我们提前创建好两个文本文件,并进行相应的数据录入,具体格式如下:

  • course.txt:
    在这里插入图片描述

  • student.txt:
    在这里插入图片描述


4.多级菜单的实现


int choose_user()
{
loop:
    system("cls");
    int c = 0;
    cout << "=================================================================" << endl;
    cout << "-------------- 欢迎来到学生选课系统 ---------------" << endl;
    cout << "请选择你的身份(1管理员 或 2学生)(输入0退出): ";
    cin >> c;

    string passwd;
    if (c == 1)
    {
        cout << "请输入密码: ";
        cin >> passwd;
        if (passwd == string(PASSWORD))		// PASSWORD是一个宏,#define PASSWORD 密码
        {
            flag = 1;
            cout << "登入成功." << endl;
            system("pause");
        }
        else
        {
            cout << "密码错误." << endl;
            system("pause");
            goto loop;
        }
    }
    else
        flag = 0;

    if (c < 0 || c > 2)
    {
        cout << "请输入 0-2." << endl;
        system("pause");
        goto loop;
    }

    return c;
}

void menu_course()
{
    int c = 0;
    while (1)
    {
        system("cls");
        cout << "============ 课程菜单 ============" << endl;
        cout << "           1. 增加课程            " << endl;
        cout << "           2. 删除课程            " << endl;
        cout << "           3. 修改课程            " << endl;
        cout << "           4. 查找课程            " << endl;
        cout << "           5. 展示所有课程        " << endl;
        cout << "           0. 返回上级目录        " << endl;
        cout << "----------------------------------" << endl;
        cout << "请选择你的操作(0-6): ";
        cin >> c;
        switch (c)
        {
        case 1:
            if (flag)
                Course().Add(cour);
            else
            {
                cout << "request denied." << endl;
                system("pause");
            }
            break;
        case 2:
            if (flag)
                Course().Delete(cour);
            else
            {
                cout << "request denied." << endl;
                system("pause");
            }
            break;
        case 3:
            if (flag)
                Course().Modify(cour);
            else
            {
                cout << "request denied." << endl;
                system("pause");
            }
            break;
        case 4:
            Course().Lookup(cour);
            break;
        case 5:
            Course().Show(cour);
            break;
        case 0:
            cout << "------------ 返回成功 ------------" << endl;
            system("pause");
            return;
        default:
            cout << "请输入 0-6." << endl;
            system("pause");
            break;
        }
    }
}

void menu_student()
{
    int c = 0;
    while (1)
    {
        system("cls");
        cout << "============ 学生菜单 ============" << endl;
        cout << "           1. 添加学生            " << endl;
        cout << "           2. 删除学生            " << endl;
        cout << "           3. 修改学生            " << endl;
        cout << "           4. 查找学生            " << endl;
        cout << "           5. 展示所有学生信息    " << endl;
        cout << "           6. 选课                " << endl;
        cout << "           7. 退选                " << endl;
        cout << "           0. 返回                " << endl;
        cout << "----------------------------------" << endl;
        cout << "请选择你的操作(0-7): ";
        cin >> c;
        switch (c)
        {
        case 1:
            if (flag)
                Student().Add(stu);
            else
            {
                cout << "request denied." << endl;
                system("pause");
            }
            break;
        case 2:
            if (flag)
                Student().Delete(stu);
            else
            {
                cout << "request denied." << endl;
                system("pause");
            }
            break;
        case 3:
            if (flag)
                Student().Modify(stu);
            else
            {
                cout << "request denied." << endl;
                system("pause");
            }
            break;
        case 4:
            Student().Lookup(stu);
            break;
        case 5:
            Student().Show(stu);
            break;
        case 6:
            Student().Select(cour, stu);
            break;
        case 7:
            Student().Deselect(cour, stu);
            break;
        case 0:
            cout << "------------ 返回成功 ------------" << endl;
            system("pause");
            return;
        default:
            cout << "请输入 0-7." << endl;
            system("pause");
            break;
        }
    }
}

int menu_main()
{
    int c = 0;
    while (1)
    {
        system("cls");
        cout << "==========================================" << endl;
        cout << "               1. 课程菜单                " << endl;
        cout << "               2. 学生菜单                " << endl;
        cout << "               0. 回到上级目录            " << endl;
        cout << "请选择你的操作(0-2): ";
        cin >> c;

        if (c < 0 || c > 2)
        {
            cout << "请输入 0-2." << endl;
            system("pause");
        }
        else
            break;
    }

    return c;
}


int main()
{
    cour.reserve(100);
    stu.reserve(100);
    while (1)
    {
    loop:
        if (!choose_user())
        {
            cout << "=============== 谢谢使用!再见! ===============" << endl;
            return 0;
        }
        while (1)
        {
            switch (menu_main())
            {
            case 1:
                menu_course();
                break;
            case 2:
                menu_student();
                break;
            case 0:
                cout << "=============== 返回成功 ===============" << endl;
                system("pause");
                goto loop;
            default:
                cout << "请输入 0-2." << endl;
                system("pause");
                break;
            }
        }
    }
    return 0;
}

这个菜单的实现基本和上一个版本相同,只不过密码处做了些许改动。定义了一个宏PASSWORD,方便后续的维护。


5.选课和退选的实现


class Student
{
public:
    
    // ...

	// 选课
    void Select(vector<Course>& cour, vector<Student>& stu)
    {
        system("cls");
        int n_cour = Course().Read(cour);
        int n_stu = Read(stu);
        int i = 0;              // 学生
        int j = 0;              // 课程

        string id_c;            // 课程  
        string id_s;            // 学生                                                                           
        cout << "============ 开始选课 ============" << endl;
        cout << "请输入学生学号: ";
        cin >> id_s;
        while (i < n_stu && stu[i]._id != id_s)
            i++;

        if (i == n_stu)
        {
            cout << "找不到该学生。" << endl;
            system("pause");
            return;
        }

        cout << ("请输入想选择的课程编号: ");
        cin >> id_c;
        while (j < n_cour && cour[j].c_id() != id_c)
            j++;

        if (j == n_cour)
        {
            cout << "找不到该课程" << endl;
            system("pause");
            return;
        }

        if (cour[j].c_count() >= 60)
        {
            cout << "课程人数已达上限,选课失败。" << endl;
            system("pause");
        }
        else
        {
            if (cour[j].c_type())
                if (stu[i]._num_compulsory < 2)
                {
                    int c = 0;
                    while (c < stu[i]._num_compulsory && cour[j].c_id() != stu[i]._cour_compulsory[c].c_id())
                        c++;

                    if (c < stu[i]._num_compulsory)
                    {
                        cout << "请勿重复选择课程。" << endl;
                        system("pause");
                        return;
                    }
                    stu[i]._cour_compulsory[stu[i]._num_compulsory] = cour[j];
                    stu[i]._num_compulsory++;
                    cour[j].c_count()++;
                    Course().Write(cour, n_cour);
                    Write(stu, n_stu);
                    cout << "选课成功。" << endl;
                    system("pause");
                }
                else
                {
                    cout << "必修课数量已达上限,选课失败。" << endl;
                    system("pause");
                }
            else
            {
                if (stu[i]._num_elective < 1)
                {
                    int c = 0;
                    while (c < stu[i]._num_elective && cour[j].c_id() != stu[i]._cour_elective[c].c_id())
                        c++;

                    if (c < stu[i]._num_elective)
                    {
                        cout << "请勿重复选择课程。" << endl;
                        system("pause");
                        return;
                    }

                    stu[i]._cour_elective[stu[i]._num_elective] = cour[j];
                    stu[i]._num_elective++;
                    cour[j].c_count()++;
                    Course().Write(cour, n_cour);
                    Write(stu, n_stu);
                    cout << "选课成功。" << endl;
                    system("pause");
                }
                else
                {
                    cout << "选修课数量已达上限,选课失败。" << endl;
                    system("pause");
                }
            }
        }
    }

	// 退选
    void Deselect(vector<Course>& cour, vector<Student>& stu)
    {
        system("cls");
        int n_cour = Course().Read(cour);
        int n_stu = Read(stu);
        int i = 0;              // 学生
        int j = 0;              // 课程

        string id_c;          // 课程  
        string id_s;          // 学生                                                                               
        cout << "============ 退选 ============" << endl;
        cout << "请输入学生学号: ";
        cin >> id_s;
        while (i < n_stu && stu[i]._id != id_s)
            i++;

        if (i == n_stu)
        {
            cout << "找不到该学生。" << endl;
            system("pause");
            return;
        }

        cout << ("请输入想要退选的课程编号: ");
        cin >> id_c;
        while (j < n_cour && cour[j].c_id() != id_c)
            j++;

        if (j == n_cour)
        {
            cout << "找不到该课程" << endl;
            system("pause");
            return;
        }

        if (stu[i]._num_compulsory)
        {
            int c = stu[i]._num_compulsory - 1;
            while (c >= 0)
            {
                if (stu[i]._cour_compulsory[c].c_id() == id_c)
                {
                    cour[j].c_count()--;
                    stu[i]._num_compulsory--;

                    stu[i]._cour_compulsory[c] = Course();

                    // 重新排序
                    for (; c < stu[i]._num_compulsory; c++)
                        swap(stu[i]._cour_compulsory[c], stu[i]._cour_compulsory[c + 1]);

                    Write(stu, n_stu);
                    Course().Write(cour, n_cour);
                    cout << "退选成功。" << endl;
                    system("pause");
                    return;
                }
                c--;
            }

            if (stu[i]._cour_elective)
            {
                int c = stu[i]._num_elective - 1;
                while (c >= 0)
                {
                    if (stu[i]._cour_elective[c].c_id() == id_c)
                    {
                        cour[j].c_count()--;
                        stu[i]._num_elective--;

                        stu[i]._cour_elective[c] = Course();

                        for (; c < stu[i]._num_elective; c++)
                            swap(stu[i]._cour_elective[c], stu[i]._cour_elective[c + 1]);

                        Write(stu, n_stu);
                        Course().Write(cour, n_cour);
                        cout << "退选成功。" << endl;
                        system("pause");
                        return;
                    }
                    c--;
                }
                cout << "你并未选择该课程。" << endl;
                system("pause");
                return;
            }
        }

        if (stu[i]._cour_elective)
        {
            int c = stu[i]._num_elective - 1;
            while (c >= 0)
            {
                if (stu[i]._cour_elective[c].c_id() == id_c)
                {
                    cour[j].c_count()--;
                    stu[i]._num_elective--;

                    stu[i]._cour_elective[c] = Course();

                    for (; c < stu[i]._num_elective; c++)
                        swap(stu[i]._cour_elective[c], stu[i]._cour_elective[c + 1]);

                    Write(stu, n_stu);
                    Course().Write(cour, n_cour);
                    cout << "退选成功。" << endl;
                    system("pause");
                    return;
                }
                c--;
            }
            cout << "你并未选择该课程。" << endl;
            system("pause");
            return;
        }
    }

private:
    string _id;                                 // 学号
    string _class;                              // 班级
    string _name;                               // 名字
    Course _cour_compulsory[SIZE_COMP];         // 必修课信息
    Course _cour_elective[SIZE_ELECT];          // 选修课信息
    int _num_compulsory;                        // 已选必修课数量
    int _num_elective;                          // 已选选修课数量
};

这一块的实现也和老版本没有多大区别,这里不再过多赘述,细节在我的上一篇博客中都有很详细的讲解。


5.完整代码


#define _CRT_SECURE_NO_WARNINGS

#include<iostream>
#include<fstream>
#include<string>
#include<vector>

using namespace std;

#define SIZE_COMP 2              // 可以选择的必修课数量
#define SIZE_ELECT 1             // 可选择的选修课数量
#define PASSWORD "123456"        // 管理员密码

int flag = 0;                    // 确定身份状态的状态变量,0是学生,1是管理员,默认是0

class Student;                   // 向前声明学生类

class Course
{
    friend ostream& operator<<(ostream& out, const Course& c);
    friend fstream& operator<<(fstream& fout, const Course& c);
    // friend istream& operator>>(istream& in, Course& c);        这个重载不好实现,因为要查重
    friend fstream& operator>>(fstream& fin, Course& c);

    friend ostream& operator<<(ostream& out, const Student& s);

public:
    Course()
        : _id("None")
        , _name("None")
        , _type(0)
        , _hour(0)
        , _credir(0)
        , _count(0)
    {}

    const string c_id() { return _id; }                   // 编号的接口
    const string c_name() { return _name; }               // 名字的接口
    int& c_count() { return _count; }                     // 选课人数的接口
    const bool c_type() { return _type; }                 // 类型接口


    void Write(vector<Course>& cour, int n)
    {
        fstream myfile;
        myfile.open("course.txt", ios::out | ios::binary);
        if (!myfile)
        {
            cout << "course.txt can't open." << endl;
            abort();
        }

        myfile << n << endl << endl;
        for (int i = 0; i < n; i++)
            myfile << cour[i] << endl;

        myfile.close();
    }

    int Read(vector<Course>& cour)
    {
        cour.clear();
        fstream myfile;
        myfile.open("course.txt", ios::in | ios::binary);
        if (!myfile)
        {
            cout << "course.txt can't open." << endl;
            abort();
        }

        int n;
        myfile.seekg(0);
        myfile >> n;

        Course temp;
        for (int i = 0; i < n; i++)
        {
            myfile >> temp;
            cour.push_back(temp);
        }

        myfile.close();
        return n;
    }

    void Add(vector<Course>& cour)
    {
        system("cls");
        int n = Read(cour);
        char sign = '0';
        Course temp;

        cout << "============ 增加课程信息 ============" << endl;
        while (sign != 'n' && sign != 'N')
        {
        loop:
            cout << "ID: ";
            cin >> temp._id;

            // 查重
            int c = 0;
            while (c < n)
            {
                c++;
                if (temp._id == cour[n - c]._id)
                {
                    cout << "编号重复,请重新输入。" << endl;
                    goto loop;
                }
            }

            cout << "课程名: ";
            cin >> temp._name;
            cout << "课程类型(1必修,0选修): ";
            cin >> temp._type;
            cout << "学时: ";
            cin >> temp._hour;
            cout << "学分: ";
            cin >> temp._credir;
            
            n++;

            cour.push_back(temp);

            cout << "是否继续添加(y 或 n)";
            cin >> sign;
        }
        // 保存进文件
        Write(cour, n);
    }

    void Delete(vector<Course>& cour)
    {
        system("cls");
        int n = Read(cour);
        int i = 0;
        string id;

        cout << "============ 删除课程 ============" << endl;
        cout << "请输入需要删除课程的编号: ";
        cin >> id;

        // 检查有没有这个课程
        while (i < n && id != cour[i]._id)
            i++;

        if (i == n)
        {
            cout << "没找到该课程。" << endl;
            system("pause");
            return;
        }
        else
        {
            if (cour[i]._count)
            {
                cout << "所选人数不为零,请联系所有学生退选后,再删除该课程。" << endl;
                system("pause");
                return;
            }
        }

        for (int j = i; j < n - 1; j++)
            cour[j] = cour[j + 1];              // 编译器自动生成的赋值运算符重载

        // 保存
        char sign;
        cout << "是否保存(y 或 n): ";
        cin >> sign;
        if (sign != 'n' && sign != 'N')
        {
            cour.erase(cour.end() - 1);
            Write(cour, n - 1);
            cout << "============ 删除成功 ============" << endl;
            system("pause");
        }
    }

    void Modify(vector<Course>& cour)
    {
        system("cls");
        int n = Read(cour);
        string id;
        int i = 0;

        cout << "============ 修改课程信息 ============" << endl;
        cout << "请输入你想修改的课程id: ";
        cin >> id;

        // 看有没有这个课程
        cin >> id;
        while (i < n && id != cour[i]._id)
            i++;

        if (i == n)
        {
            cout << "没有找到该课程。" << endl;
            system("pause");
            return;
        }
        else
        {
            if (cour[i]._count)
            {
                cout << "所选人数不为零,请联系所有学生退选后,再修改课程信息。" << endl;
                system("pause");
                return;
            }
        }

        cout << "-------------------------------------------------" << endl;
        cout << "编号" << "\t" << "课程名" << "\t" << "类型"     << "\t"
             << "学时" << "\t" << "学分"   << "\t" << "选课人数" << endl;
        cout << cour[i] << endl;
        cout << "-------------------------------------------------" << endl;

        cout << "请重新输入课程信息。" << endl;
        cout << "课程名: ";
        cin >> cour[i]._name;
        cout << "课程类型(1必修,0选修): ";
        cin >> cour[i]._type;
        cout << "学时: ";
        cin >> cour[i]._hour;
        cout << "学分: ";
        cin >> cour[i]._credir;

        // 保存
        char sign;
        cout << "是否保存修改(y 或 n): ";
        cin >> sign;
        if (sign != 'n' && sign != 'N')
        {
            Write(cour, n);
            cout << "============ 修改成功 ============" << endl;
            system("pause");
        }
    }

    void Lookup(vector<Course>& cour)
    {
        system("cls");
        int n = Read(cour);
        int i = 0;
        string id;
        
        cout << "============ 查找课程 ============" << endl;
        cout << "请输入要查找课程的编号: ";
        cin >> id;

        // 检查是否存在
        while (i < n && id != cour[i]._id)
            i++;

        if (i == n)
        {
            cout << "没有找到该课程。" << endl;
        }
        else
        {
            cout << "-------------------------------------------------" << endl;
            cout << "编号" << "\t" << "课程名" << "\t" << "类型"     << "\t"
                 << "学时" << "\t" << "学分"   << "\t" << "选课人数" << endl;
            cout << "-------------------------------------------------" << endl;
            cout << cour[i] << endl;
        }

        system("pause");
    }

    void Show(vector<Course>& cour)
    {
        system("cls");
        int n = Read(cour);

        cout << "============ 展示所有课程信息 ============" << endl;
        cout << "-------------------------------------------------" << endl;
        cout << "编号" << "\t" << "课程名" << "\t" << "类型"     << "\t"
             << "学时" << "\t" << "学分"   << "\t" << "选课人数" << endl;
        cout << "-------------------------------------------------" << endl;
        for (int i = 0; i < n; i++)
            cout << cour[i] << endl;

        system("pause");
    }

private:
    string _id;         // 编号
    string _name;       // 课程名
    bool _type;         // 课程类型,1必修,0选修
    int _hour;          // 学时
    int _credir;        // 学分
    int _count;         // 选课人数
};

vector<Course> cour;

ostream& operator<<(ostream& out, const Course& c)
{
    out << c._id   << "\t" << c._name   << "\t" << (c._type ? "必修" : "选修") << "\t"
        << c._hour << "\t" << c._credir << "\t" << c._count;
    return out;
}

fstream& operator<<(fstream& fout, const Course& c)
{
    fout << c._id   << "\t" << c._name   << "\t" << c._type << "\t"
         << c._hour << "\t" << c._credir << "\t" << c._count;
    return fout;
}

fstream& operator>>(fstream& fin, Course& c)
{
    fin >> c._id   >> c._name   >> c._type
        >> c._hour >> c._credir >> c._count;
    return fin;
}

class Student
{
    friend ostream& operator<<(ostream& out, const Student& s);
    friend fstream& operator<<(fstream& fout, const Student& s);
    // friend istream& operator>>(istream& in, Student& s);        这个重载不好实现,因为要查重
    friend fstream& operator>>(fstream& fin, Student& s);
public:
    Student()
        : _id("None")                       // 学号
        , _class("None")                    // 班级
        , _name("None")                     // 姓名
        , _num_compulsory(0)                
        , _num_elective(0)
    {}

    void Write(vector<Student>& stu, int n)
    {
        fstream myfile;
        myfile.open("student.txt", ios::out | ios::binary);
        if (!myfile)
        {
            cout << "student.txt can't open." << endl;
            abort();
        }

        myfile << n << endl << endl;
        for (int i = 0; i < n; i++)
            myfile << stu[i] << endl;

        myfile.close();
    }

    int Read(vector<Student>& stu)
    {
        stu.clear();
        fstream myfile;
        myfile.open("student.txt", ios::in | ios::binary);
        if (!myfile)
        {
            cout << "student.txt can't open." << endl;
            abort();
        }

        int n;
        myfile.seekg(0);
        myfile >> n;

        Student temp;

        for (int i = 0; i < n; i++)
        {
            myfile >> temp;
            stu.push_back(temp);
        }

        myfile.close();
        return n;
    }

    void Add(vector<Student>& stu)
    {
        system("cls");
        int n = Read(stu);
        char sign = '0';
        Student temp;

        cout << "============ 添加学生 ============" << endl;
        while (sign != 'n' && sign != 'N')
        {
        loop:
            cout << "学号: ";
            cin >> temp._id;

            // 检查重复
            int c = 0;
            while (c < n)
            {
                c++;
                if (temp._id == stu[n - c]._id)
                {
                    cout << "学号重复,请重新输入。" << endl;
                    goto loop;
                }
            }

            cout << "班级: ";
            cin >> temp._class;
            cout << "姓名: ";
            cin >> temp._name;
            n++;

            stu.push_back(temp);

            cout << "是否继续添加(y 或 n): ";
            cin >> sign;
        }

        Write(stu, n);
    }

    void Delete(vector<Student>& stu)
    {
        system("cls");
        int n = Read(stu);
        int m = Course().Read(cour);                    // 课程数量
        int i = 0;
        string id;

        cout << "============ 删除学生 =============" << endl;
        cout << "请输入要删除学生的学号: ";
        cin >> id;

        while (i < n && id != stu[i]._id)
            i++;

        if (i == n)
        {
            cout << "没有找到该学生。" << endl;
            system("pause");
            return;
        }

        // 找到该学生所选的全部课程,并让这些课程的选课人数-1
        if (stu[i]._num_compulsory)
        {
            while (stu[i]._num_compulsory > 0)
            {
                stu[i]._num_compulsory--;

                int c = 0;
                while (c < m)
                {
                    if (stu[i]._cour_compulsory[stu[i]._num_compulsory].c_id() == cour[c].c_id())
                    {
                        cour[c].c_count()--;
                        break;
                    }
                    c++;
                }
            }
        }
        else if (stu[i]._num_elective)
        {
            while (stu[i]._num_elective > 0)
            {
                stu[i]._num_elective--;

                int c = 0;
                while (c < m)
                {
                    if (stu[i]._cour_elective[stu[i]._num_elective].c_id() == cour[c].c_id())
                    {
                        cour[c].c_count()--;
                        break;
                    }
                    c++;
                }
            }
        }

        for (int j = i; j < n - 1; j++)
            stu[j] = stu[j + 1];

        // 保存
        char sign;
        cout << "请确定是否删除(y 或 n): ";
        cin >> sign;
        if (sign != 'n' && sign != 'N')
        {
            stu.erase(stu.end() - 1);
            Write(stu, n - 1);
            Course().Write(cour, m);
            cout << "============ 删除成功 ============" << endl;
            system("pause");
        }
    }

    void Modify(vector<Student>& stu)
    {
        system("cls");
        int n = Read(stu);
        string id;
        int i = 0;

        cout << "============ 修改学生信息 ===========" << endl;
        cout << "请输入你想修改学生的学号: ";
        cin >> id;

        while (i < n && id != stu[i]._id)
            i++;

        if (i == n)
        {
            cout << "找不到该学生。" << endl;
            system("pause");
            return;
        }

        cout << "-------------------------------------------------------" << endl;
        cout << "学号: " << stu[i]._id    << endl;
        cout << "班级: " << stu[i]._class << endl;
        cout << "姓名: " << stu[i]._name  << endl;
        cout << "-------------------------------------------------------" << endl;

        cout << "请重新输入学生信息。" << endl;
        cout << "班级: ";
        cin >> stu[i]._class;
        cout << "姓名: ";
        cin >> stu[i]._name;

        // 保存
        char sign;
        cout << "是否保存修改(y 或 n): ";
        cin >> sign;
        if (sign != 'n' && sign != 'N')
        {
            cout << "修改成功。" << endl;
            Write(stu, n);
            system("pause");
        }
    }

    void Lookup(vector<Student>& stu)
    {
        system("cls");
        int n = Read(stu);
        Course().Read(cour);
        int i = 0;
        string id;

        cout << "============== 查找学生 ==============" << endl;
        cout << "请输入要查找学生的学号: ";
        cin >> id;

        while (i < n && id != stu[i]._id)
            i++;

        if (i == n)
        {
            cout << "找不到该学生。" << endl;
        }
        else
        {
            cout << stu[i] << endl;
        }

        system("pause");
    }

    void Show(vector<Student>& stu)
    {
        system("cls");
        int n = Read(stu);

        cout << "=============================== 展示所有学生信息 ==============================" << endl;
        cout << "学号" << "\t" << "班级" << "\t" << "姓名" << "\t" << "必修课" << "\t" << "选修课" << endl;
        cout << "-------------------------------------------------------------------------------" << endl;
        for (int i = 0; i < n; i++)
            cout << stu[i] << endl;

        system("pause");
    }

    void Select(vector<Course>& cour, vector<Student>& stu)
    {
        system("cls");
        int n_cour = Course().Read(cour);
        int n_stu = Read(stu);
        int i = 0;              // 学生
        int j = 0;              // 课程

        string id_c;            // 课程  
        string id_s;            // 学生                                                                           
        cout << "============ 开始选课 ============" << endl;
        cout << "请输入学生学号: ";
        cin >> id_s;
        while (i < n_stu && stu[i]._id != id_s)
            i++;

        if (i == n_stu)
        {
            cout << "找不到该学生。" << endl;
            system("pause");
            return;
        }

        cout << ("请输入想选择的课程编号: ");
        cin >> id_c;
        while (j < n_cour && cour[j].c_id() != id_c)
            j++;

        if (j == n_cour)
        {
            cout << "找不到该课程" << endl;
            system("pause");
            return;
        }

        if (cour[j].c_count() >= 60)
        {
            cout << "课程人数已达上限,选课失败。" << endl;
            system("pause");
        }
        else
        {
            if (cour[j].c_type())
                if (stu[i]._num_compulsory < 2)
                {
                    int c = 0;
                    while (c < stu[i]._num_compulsory && cour[j].c_id() != stu[i]._cour_compulsory[c].c_id())
                        c++;

                    if (c < stu[i]._num_compulsory)
                    {
                        cout << "请勿重复选择课程。" << endl;
                        system("pause");
                        return;
                    }
                    stu[i]._cour_compulsory[stu[i]._num_compulsory] = cour[j];
                    stu[i]._num_compulsory++;
                    cour[j].c_count()++;
                    Course().Write(cour, n_cour);
                    Write(stu, n_stu);
                    cout << "选课成功。" << endl;
                    system("pause");
                }
                else
                {
                    cout << "必修课数量已达上限,选课失败。" << endl;
                    system("pause");
                }
            else
            {
                if (stu[i]._num_elective < 1)
                {
                    int c = 0;
                    while (c < stu[i]._num_elective && cour[j].c_id() != stu[i]._cour_elective[c].c_id())
                        c++;

                    if (c < stu[i]._num_elective)
                    {
                        cout << "请勿重复选择课程。" << endl;
                        system("pause");
                        return;
                    }

                    stu[i]._cour_elective[stu[i]._num_elective] = cour[j];
                    stu[i]._num_elective++;
                    cour[j].c_count()++;
                    Course().Write(cour, n_cour);
                    Write(stu, n_stu);
                    cout << "选课成功。" << endl;
                    system("pause");
                }
                else
                {
                    cout << "选修课数量已达上限,选课失败。" << endl;
                    system("pause");
                }
            }
        }
    }

    void Deselect(vector<Course>& cour, vector<Student>& stu)
    {
        system("cls");
        int n_cour = Course().Read(cour);
        int n_stu = Read(stu);
        int i = 0;              // 学生
        int j = 0;              // 课程

        string id_c;          // 课程  
        string id_s;          // 学生                                                                               
        cout << "============ 退选 ============" << endl;
        cout << "请输入学生学号: ";
        cin >> id_s;
        while (i < n_stu && stu[i]._id != id_s)
            i++;

        if (i == n_stu)
        {
            cout << "找不到该学生。" << endl;
            system("pause");
            return;
        }

        cout << ("请输入想要退选的课程编号: ");
        cin >> id_c;
        while (j < n_cour && cour[j].c_id() != id_c)
            j++;

        if (j == n_cour)
        {
            cout << "找不到该课程" << endl;
            system("pause");
            return;
        }

        if (stu[i]._num_compulsory)
        {
            int c = stu[i]._num_compulsory - 1;
            while (c >= 0)
            {
                if (stu[i]._cour_compulsory[c].c_id() == id_c)
                {
                    cour[j].c_count()--;
                    stu[i]._num_compulsory--;

                    stu[i]._cour_compulsory[c] = Course();

                    // 重新排序
                    for (; c < stu[i]._num_compulsory; c++)
                        swap(stu[i]._cour_compulsory[c], stu[i]._cour_compulsory[c + 1]);

                    Write(stu, n_stu);
                    Course().Write(cour, n_cour);
                    cout << "退选成功。" << endl;
                    system("pause");
                    return;
                }
                c--;
            }

            if (stu[i]._cour_elective)
            {
                int c = stu[i]._num_elective - 1;
                while (c >= 0)
                {
                    if (stu[i]._cour_elective[c].c_id() == id_c)
                    {
                        cour[j].c_count()--;
                        stu[i]._num_elective--;

                        stu[i]._cour_elective[c] = Course();

                        for (; c < stu[i]._num_elective; c++)
                            swap(stu[i]._cour_elective[c], stu[i]._cour_elective[c + 1]);

                        Write(stu, n_stu);
                        Course().Write(cour, n_cour);
                        cout << "退选成功。" << endl;
                        system("pause");
                        return;
                    }
                    c--;
                }
                cout << "你并未选择该课程。" << endl;
                system("pause");
                return;
            }
        }

        if (stu[i]._cour_elective)
        {
            int c = stu[i]._num_elective - 1;
            while (c >= 0)
            {
                if (stu[i]._cour_elective[c].c_id() == id_c)
                {
                    cour[j].c_count()--;
                    stu[i]._num_elective--;

                    stu[i]._cour_elective[c] = Course();

                    for (; c < stu[i]._num_elective; c++)
                        swap(stu[i]._cour_elective[c], stu[i]._cour_elective[c + 1]);

                    Write(stu, n_stu);
                    Course().Write(cour, n_cour);
                    cout << "退选成功。" << endl;
                    system("pause");
                    return;
                }
                c--;
            }
            cout << "你并未选择该课程。" << endl;
            system("pause");
            return;
        }
    }

private:
    string _id;                                 // 学号
    string _class;                              // 班级
    string _name;                               // 名字
    Course _cour_compulsory[SIZE_COMP];         // 必修课信息
    Course _cour_elective[SIZE_ELECT];          // 选修课信息
    int _num_compulsory;                        // 已选必修课数量
    int _num_elective;                          // 已选选修课数量
};

vector<Student> stu;

ostream& operator<<(ostream& out, const Student& s)
{
    out << s._id << "\t" << s._class << "\t" << s._name << "\t";
   for (int i = 0; i < SIZE_COMP; i++)
       out << s._cour_compulsory[i]._name << " ";
   out << "\t";
   for (int i = 0; i < SIZE_ELECT; i++)
       out << s._cour_elective[i]._name << " ";
    return out;
}

fstream& operator<<(fstream& fout, const Student& s)
{
    fout << s._id << "\t" << s._class << "\t" << s._name << "\t";
    for (int i = 0; i < SIZE_COMP; i++)
        fout << s._cour_compulsory[i] << "\t";
    for (int i = 0; i < SIZE_ELECT; i++)
        fout << s._cour_elective[i] << "\t";
    fout << s._num_compulsory << "\t" << s._num_elective;
    return fout;
}

fstream& operator>>(fstream& fin, Student& s)
{
    fin >> s._id >> s._class >> s._name;
    for (int i = 0; i < SIZE_COMP; i++)
        fin >> s._cour_compulsory[i];
    for (int i = 0; i < SIZE_ELECT; i++)
        fin >> s._cour_elective[i];
    fin >> s._num_compulsory >> s._num_elective;
    return fin;
}

// --------------------------------------------------------------------------------------------------//

int choose_user()
{
loop:
    system("cls");
    int c = 0;
    cout << "=================================================================" << endl;
    cout << "-------------- 欢迎来到学生选课系统 ---------------" << endl;
    cout << "请选择你的身份(1管理员 或 2学生)(输入0退出): ";
    cin >> c;

    string passwd;
    if (c == 1)
    {
        cout << "请输入密码: ";
        cin >> passwd;
        if (passwd == string(PASSWORD))
        {
            flag = 1;
            cout << "登入成功." << endl;
            system("pause");
        }
        else
        {
            cout << "密码错误." << endl;
            system("pause");
            goto loop;
        }
    }
    else
        flag = 0;

    if (c < 0 || c > 2)
    {
        cout << "请输入 0-2." << endl;
        system("pause");
        goto loop;
    }

    return c;
}

void menu_course()
{
    int c = 0;
    while (1)
    {
        system("cls");
        cout << "============ 课程菜单 ============" << endl;
        cout << "           1. 增加课程            " << endl;
        cout << "           2. 删除课程            " << endl;
        cout << "           3. 修改课程            " << endl;
        cout << "           4. 查找课程            " << endl;
        cout << "           5. 展示所有课程        " << endl;
        cout << "           0. 返回上级目录        " << endl;
        cout << "----------------------------------" << endl;
        cout << "请选择你的操作(0-6): ";
        cin >> c;
        switch (c)
        {
        case 1:
            if (flag)
                Course().Add(cour);
            else
            {
                cout << "request denied." << endl;
                system("pause");
            }
            break;
        case 2:
            if (flag)
                Course().Delete(cour);
            else
            {
                cout << "request denied." << endl;
                system("pause");
            }
            break;
        case 3:
            if (flag)
                Course().Modify(cour);
            else
            {
                cout << "request denied." << endl;
                system("pause");
            }
            break;
        case 4:
            Course().Lookup(cour);
            break;
        case 5:
            Course().Show(cour);
            break;
        case 0:
            cout << "------------ 返回成功 ------------" << endl;
            system("pause");
            return;
        default:
            cout << "请输入 0-6." << endl;
            system("pause");
            break;
        }
    }
}

void menu_student()
{
    int c = 0;
    while (1)
    {
        system("cls");
        cout << "============ 学生菜单 ============" << endl;
        cout << "           1. 添加学生            " << endl;
        cout << "           2. 删除学生            " << endl;
        cout << "           3. 修改学生            " << endl;
        cout << "           4. 查找学生            " << endl;
        cout << "           5. 展示所有学生信息    " << endl;
        cout << "           6. 选课                " << endl;
        cout << "           7. 退选                " << endl;
        cout << "           0. 返回                " << endl;
        cout << "----------------------------------" << endl;
        cout << "请选择你的操作(0-7): ";
        cin >> c;
        switch (c)
        {
        case 1:
            if (flag)
                Student().Add(stu);
            else
            {
                cout << "request denied." << endl;
                system("pause");
            }
            break;
        case 2:
            if (flag)
                Student().Delete(stu);
            else
            {
                cout << "request denied." << endl;
                system("pause");
            }
            break;
        case 3:
            if (flag)
                Student().Modify(stu);
            else
            {
                cout << "request denied." << endl;
                system("pause");
            }
            break;
        case 4:
            Student().Lookup(stu);
            break;
        case 5:
            Student().Show(stu);
            break;
        case 6:
            Student().Select(cour, stu);
            break;
        case 7:
            Student().Deselect(cour, stu);
            break;
        case 0:
            cout << "------------ 返回成功 ------------" << endl;
            system("pause");
            return;
        default:
            cout << "请输入 0-7." << endl;
            system("pause");
            break;
        }
    }
}

int menu_main()
{
    int c = 0;
    while (1)
    {
        system("cls");
        cout << "==========================================" << endl;
        cout << "               1. 课程菜单                " << endl;
        cout << "               2. 学生菜单                " << endl;
        cout << "               0. 回到上级目录            " << endl;
        cout << "请选择你的操作(0-2): ";
        cin >> c;

        if (c < 0 || c > 2)
        {
            cout << "请输入 0-2." << endl;
            system("pause");
        }
        else
            break;
    }

    return c;
}


int main()
{
    cour.reserve(100);
    stu.reserve(100);
    while (1)
    {
    loop:
        if (!choose_user())
        {
            cout << "=============== 谢谢使用!再见! ===============" << endl;
            return 0;
        }
        while (1)
        {
            switch (menu_main())
            {
            case 1:
                menu_course();
                break;
            case 2:
                menu_student();
                break;
            case 0:
                cout << "=============== 返回成功 ===============" << endl;
                system("pause");
                goto loop;
            default:
                cout << "请输入 0-2." << endl;
                system("pause");
                break;
            }
        }
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1353518.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【含ROM】小米刷机之k30pro刷澎湃系统

本教程以我的k30 pro 变焦为例。(同k30 pro) 目录 [ - ] 解bl锁 [ - ] 下载rom [ - ] 开始刷机 [ - ] k30 pro 澎湃下载链接 [ - ] 其他相关资源下载链接 一. 解bl锁 百度一下 小米解bl锁 有很多教程。 建议参考小米社区官网的解锁教程&#xff1a; https://web.vip.miui.co…

Redis:原理速成+项目实战——Redis实战4(解决Redis缓存穿透、雪崩、击穿)

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位大四、研0学生&#xff0c;正在努力准备大四暑假的实习 &#x1f30c;上期文章&#xff1a;Redis&#xff1a;原理项目实战——Redis实战3&#xff08;Redis缓存最佳实践&#xff08;问题解析高级实现&#xff09;&#x…

java练习题之常用类Object类,包装类

常用类 应用知识点&#xff1a; Object类 包装类 习题&#xff1a; 1&#xff1a;(Object 类)仔细阅读以下代码&#xff0c;写出程序运行的结果&#xff1b;并简述 和 equals 的区别。 true false 是判断两个变量或实例是不是指向同一个内存空间。 比较两个引用类型的地址&…

如何做好档案数字化前的鉴定工作

要做好档案数字化前的鉴定工作&#xff0c;可以按照以下步骤进行&#xff1a; 1. 确定鉴定目标&#xff1a;明确要鉴定的档案的内容、数量和性质&#xff0c;确定鉴定的范围和目标。 2. 进行档案清点&#xff1a;对档案进行全面清点和登记&#xff0c;包括数量、种类、状况等信…

鸿蒙HarmonyOs学习:如何添页面和路由

1.目录结构 重点我们开发中需要用到地方我都做了简单的说明。 2.我们看看入口页面是如何配置的 在主配置文件module.json5中配置Ability路径已经应用图标和应用名称等信息。 3.配置页面路由 这个路由是由哪儿配置的呢&#xff1f; 想必看完这些&#xff0c;你应该知道一个鸿…

算法练习Day23 (Leetcode/Python-回溯算法)

46. Permutations Given an array nums of distinct integers, return all the possible permutations. You can return the answer in any order. Example 1: Input: nums [1,2,3] Output: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]思路&#xff1a;此题可用回溯…

C#中使用正则表达式实现汉字转拼音

目录 一、正则表达式基础 二、实例 1.程序入口Form1.cs 2.类库PinYin.cs 三、生成效果 四、实例中的知识点 1.Regex 2.ToCharArray() 3.Regex.IsMatch 方法 &#xff08;1&#xff09;定义 &#xff08;2&#xff09;重载 &#xff08;3&#xff09;IsMatch(Stri…

人工智能AI与3D视觉技术的结合正在引领新一代移动机器人的革新

随着科技的飞速发展&#xff0c;人工智能AI与3D视觉技术的结合正在引领新一代移动机器人的革新。富唯智能移动机器人&#xff0c;以其独特的3D视觉技术&#xff0c;赋予了移动机器人一双“智慧之眼”&#xff0c;从而为现代工业自动化带来了前所未有的突破。 富唯智能移动机器…

湖南大学-算法设计与分析-2023期末考试【原题】

前言 21&#xff1a;00刚刚结束的考试&#xff0c;凭着回忆把题目重现出来了&#xff0c;在复习的时候根本找不到往年的试卷&#xff0c;希望这张回忆的试卷能帮助到下一届的同学。知道题目基本上就能做出来了&#xff0c;但是不知道是真的做不出来&#xff0c;我就不给答案了…

解析一次get请求后台解码中文乱码的问题

今日遇到一个项目组中个人独有的bug&#xff0c;系统输入中文搜索内容搜不出来&#xff0c;组员都可以&#xff0c;从前台查到后台&#xff0c;发现前端的获取值和传递值都没什么问题&#xff0c;到了后台&#xff0c;接收的中文参数直接是个乱码&#xff0c;但是想到之前也有传…

跨站脚本攻击漏洞XSS绕过22种方式总结

XSS漏洞简介 跨站脚本攻击在目前这个时间节点还是属于一个排位比较高的漏洞&#xff0c;在OWASP TOP10 2021中隶属于注入型漏洞&#xff0c;高居TOP3的排位&#xff0c;可见这个漏洞的普遍性。跨站脚本攻击的学习中我们主要需要明白的是跨站的含义&#xff0c;以及XSS的核心。…

YOLO+SlowFast+DeepSORT 简单实现视频行为识别

前言 前段时间刷短视频看到过别人用摄像头自动化监控员工上班状态&#xff0c;比如标注员工是不是离开了工位&#xff0c;在位置上是不是摸鱼。虽然是段子&#xff0c;但是这个是可以用识别技术实现一下&#xff0c;于是我在网上找&#xff0c;知道发现了 SlowFast&#xff0c…

模拟Spring事件监听机制

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 之前我们一起学习了Spr…

polar CTF 简单rce

一、题目 <?php /*PolarD&N CTF*/ highlight_file(__FILE__); function no($txt){if(!preg_match("/cat|more|less|head|tac|tail|nl|od|vim|uniq|system|proc_open|shell_exec|popen| /i", $txt)){return $txt;}else{ die("whats up");}} $yyds(…

向日葵远程控制软件MySQL5.7的安装与配置

目录 一. 向日葵远程控制软件 1.1 简介 1.2 选择原因 1.3 安装及使用 1.4 使用场景 二. MySQL5.7 安装与配置 2.1 什么是MySQL 2.2 安装 MySQL5.7 2.2.1 安装步骤 2.2.2 内部连接 2.2.3 外部连接 三. 思维导图 一. 向日葵远程控制软件 1.1 简介 向日葵电脑版是一款拥有多年…

SpringCloudAlibaba之Gateway

1、简介 网关是系统唯一对外的入口&#xff0c;介于客户端与服务器端之间&#xff0c;用于对请求进行鉴权、限流、路由、监控等功能。 2、Gateway主要功能 2.1、route 路由 路由是网关的最基本组成&#xff0c;由一个路由 id、一个目标地址 url&#xff0c;一组断言工厂及一…

掌握静态S5:从入门到精通的指南

在现今的数据驱动时代&#xff0c;静态S5作为一款强大的数据分析工具&#xff0c;越来越受到各行各业的青睐。然而&#xff0c;如何从入门到精通&#xff0c;全面掌握静态S5的各项功能&#xff0c;成为了许多用户面临的挑战。本文将为你提供一份详尽的指南&#xff0c;助你顺利…

Lingo 17安装包下载及安装教程

Lingo 17下载链接&#xff1a;https://docs.qq.com/doc/DUndEVXd4WVVweGFR 1.鼠标右键解压到“Lingo 17.0” 2.双击打开【Setup】文件夹 3.选中Lingo 17.0&#xff0c;鼠标右键选择“以管理员身份运行” 4.点击“Next” 5.选中I accept the terms in the license agreement&…

【C程序设计】C循环

有的时候&#xff0c;我们可能需要多次执行同一块代码。一般情况下&#xff0c;语句是按顺序执行的&#xff1a;函数中的第一个语句先执行&#xff0c;接着是第二个语句&#xff0c;依此类推。 编程语言提供了更为复杂执行路径的多种控制结构。 循环语句允许我们多次执行一个…

Python 热力图的绘制(Matplotlib篇-12)

Python 热力图的绘制(Matplotlib篇-12)         🍹博主 侯小啾 感谢您的支持与信赖。☀️ 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ�…