做非法网站要多少钱,重庆做汉堡的餐饮公司网站,温州建设工程信息网站,广东省路桥建设有限公司网站C大作业——学生选课系统优化版 前言1.学生类和课程类的实现2.输入输出流重载的实现3.增删改查的实现4.多级菜单的实现5.选课和退选的实现5.完整代码 前言 本文是对本人之前写过的一个学生选课系统的优化#xff0c;整体上的逻辑是和我上一篇博客一样的#xff08;链接在此大作业——学生选课系统优化版 前言1.学生类和课程类的实现2.输入输出流重载的实现3.增删改查的实现4.多级菜单的实现5.选课和退选的实现5.完整代码 前言 本文是对本人之前写过的一个学生选课系统的优化整体上的逻辑是和我上一篇博客一样的链接在此https://blog.csdn.net/weixin_73870552/article/details/135298985?spm1001.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(vectorCourse cour, int n) {} // 向文件写入数据int Read(vectorCourse cour) {} // 从文件读取数据void Add(vectorCourse cour) {} // 增void Delete(vectorCourse cour) {} // 删void Modify(vectorCourse cour) {} // 改void Lookup(vectorCourse cour) {} // 查void Show(vectorCourse 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(vectorStudent stu, int n) {}int Read(vectorStudent stu) {}void Add(vectorStudent stu) {}void Delete(vectorStudent stu) {}void Modify(vectorStudent stu) {}void Lookup(vectorStudent stu) {}void Show(vectorStudent stu) {}void Select(vectorCourse cour, vectorStudent stu) {} // 选课void Deselect(vectorCourse cour, vectorStudent 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_COMP和SIZE_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.增删改查的实现 实现增删查改需要借助两个全局的动态数组。vectorCourse cour和vectorStudent 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(vectorCourse cour, int n){fstream myfile;myfile.open(course.txt, ios::out | ios::binary);if (!myfile){cout course.txt cant open. endl;abort();}myfile n endl endl;for (int i 0; i n; i)myfile cour[i] endl;myfile.close();}int Read(vectorCourse cour){cour.clear();fstream myfile;myfile.open(course.txt, ios::in | ios::binary);if (!myfile){cout course.txt cant 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(vectorCourse 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(vectorCourse 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(vectorCourse 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(vectorCourse 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(vectorCourse 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(vectorStudent stu, int n){fstream myfile;myfile.open(student.txt, ios::out | ios::binary);if (!myfile){cout student.txt cant open. endl;abort();}myfile n endl endl;for (int i 0; i n; i)myfile stu[i] endl;myfile.close();}int Read(vectorStudent stu){stu.clear();fstream myfile;myfile.open(student.txt, ios::in | ios::binary);if (!myfile){cout student.txt cant 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(vectorStudent 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(vectorStudent 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;}// 找到该学生所选的全部课程并让这些课程的选课人数-1if (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(vectorStudent 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(vectorStudent 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(vectorStudent 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;}}elseflag 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);}elsebreak;}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(vectorCourse cour, vectorStudent 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(vectorCourse cour, vectorStudent 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#includeiostream
#includefstream
#includestring
#includevectorusing namespace std;#define SIZE_COMP 2 // 可以选择的必修课数量
#define SIZE_ELECT 1 // 可选择的选修课数量
#define PASSWORD 123456 // 管理员密码int flag 0; // 确定身份状态的状态变量0是学生1是管理员默认是0class 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(vectorCourse cour, int n){fstream myfile;myfile.open(course.txt, ios::out | ios::binary);if (!myfile){cout course.txt cant open. endl;abort();}myfile n endl endl;for (int i 0; i n; i)myfile cour[i] endl;myfile.close();}int Read(vectorCourse cour){cour.clear();fstream myfile;myfile.open(course.txt, ios::in | ios::binary);if (!myfile){cout course.txt cant 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(vectorCourse 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(vectorCourse 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(vectorCourse 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(vectorCourse 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(vectorCourse 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; // 选课人数
};vectorCourse 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(vectorStudent stu, int n){fstream myfile;myfile.open(student.txt, ios::out | ios::binary);if (!myfile){cout student.txt cant open. endl;abort();}myfile n endl endl;for (int i 0; i n; i)myfile stu[i] endl;myfile.close();}int Read(vectorStudent stu){stu.clear();fstream myfile;myfile.open(student.txt, ios::in | ios::binary);if (!myfile){cout student.txt cant 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(vectorStudent 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(vectorStudent 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;}// 找到该学生所选的全部课程并让这些课程的选课人数-1if (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(vectorStudent 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(vectorStudent 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(vectorStudent 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(vectorCourse cour, vectorStudent 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(vectorCourse cour, vectorStudent 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; // 已选选修课数量
};vectorStudent 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;}}elseflag 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);}elsebreak;}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;
}