大一期末程序课程设计 CC++实现简单学生学籍管理系统

    技术2025-12-02  20

    链表实现C/C++简单学生学籍管理系统。

    实验结果图: 剩下的操作有兴趣的话复制粘贴去试试:

    //Main.cpp #include"ManagerStu.h" int Student::AGE[] = { 0 }; int Student::CLNUM[] = { 0 }; string Student::DEPART[] = { " " }; int Student::departTypes = 0; int Student::sizes = 0; int main() { ManagerStu p; p.start(); return 0; }

    Student类:

    //Student.h #pragma once #include<iostream> #include<fstream> #include<iomanip> using namespace std; class Student { public: Student(); void setBasic();//录入 void changeStu();//修改人员信息 Student* delMessage(int nums);//删除人员信息 Student* searchStu(int nums);//根据编号查找人员 Student* searchStu(string names);//根据姓名查找人员 Student* searchStuSex(string sex);//根据性别查找人员 Student* searchStuAge(int age);//根据年龄查找人员 Student* searchStuClass(int classNum);//根据班号查找人员 Student* searchStuDepart(string Depart);//根据系别查找人员 void searchAll();//调用上述查找函数 //判断输入是否合法 bool judgeNums(int num);//学号 bool judgeClass(int num);//班号 bool judgeSex(string u);//性别 bool judgeName(string& inStr);//名字 bool judgeAge(int num);//年龄 //容错,分别对应(调用)上面函数 void judge1(int num);//学号 void judge2(int num);//班号 void judge3(string u);//性别 void judge4(string& inStr);//名字 void judge5(int num);//年龄 void statisticsSex();//根据性别统计人数 void statisticsClass();//根据班号统计人数 void statisticsAge();//根据年龄统计人数 void statisticsDepart();//根据系别统计人数 void statisticsAll();//调用上述统计函数 void showMess();//输出学生信息 void showBasic(); void setBasicFile();//批量录入 void writeF(ofstream& ofs); static int AGE[31];//年龄1-30 static int CLNUM[201];//班号1-200 static string DEPART[15];//系别的名称 static int departTypes;//系别类型个数 static int sizes;//总人数 Student* next = NULL;//指针 private: int nums;//学号(10位) string name;//名字 string sex;//性别 int age;//年龄 string department;//系别 string majoy;//专业 int classNum;//班号 }; //Student.cpp #include"Student.h" Student::Student() { nums = 0; name = " "; sex = " "; age = 0; classNum = 0; majoy = " "; department = " "; } void Student::setBasic() {//设置基本信息 cout << "依次输入学生的学号、姓名、性别、年龄、系、专业、班号:\n"; cin >> nums; judge1(nums); cin >> name; judge4(name); cin >> sex; judge3(sex); cin >> age; judge5(age); cin >> department >> majoy; cin>> classNum; judge2(classNum); sizes++; CLNUM[classNum]++; AGE[age]++; int i = 0; while (i < departTypes) { if (DEPART[i] == department) break; i++; } if (i == departTypes) { DEPART[i] = department; departTypes++; } } Student* Student::delMessage(int nums) {//根据学号nums删除学生 Student* p = this; Student* pLast = NULL; while (p != NULL) { if (p->nums != nums) { pLast = p; p = p->next; } else break; } if (p == NULL) { cout << "查无此人!无法进行删除。\n"; return NULL; } else { if (p->nums == this->nums) return p->next;//如果是表头,返回表头的next else { pLast->next = p->next; AGE[p->age]--; CLNUM[p->classNum]--; delete p; return this; } } } void Student::changeStu() {//修改信息 cout << "输入相应学生的学号,进行修改信息:\n"; int u; cin >> u; int times = 3; while (times-- && !judgeNums(u)) cin >> u; Student* p = this; while (p != NULL) { if (p->nums != u) p = p->next; else break; } cout << "输入对应操作数进行修改:\n"; cout << "1.学号 2.姓名 3.性别 4.年龄 5.系别 6.专业 7.班号\n"; int oper; cin >> oper; switch (oper) { case 1: cout << "输入学号:"; cin >> p->nums; p->judge1(p->nums); break; case 2: cout << "输入姓名:"; cin >> p->name; p->judge4(p->name); break; case 3: cout << "输入性别:"; cin >> p->sex; p->judge3(p->sex); break; case 4: cout << "输入年龄:"; cin >> p->age; p->judge5(p->age); break; case 5: cout << "输入系别:"; cin >> p->department; break; case 6: cout << "输入专业:"; cin >> p->majoy; break; case 7: cout << "输入班号:"; cin >> p->classNum; p->judge2(p->classNum); break; default: break; } } Student* Student::searchStu(int nums) {//根据学号寻找学生 //修改后的: Student* p = this;//得到已有的链表 Student* u = NULL;//返回的节点 while (p != NULL) { if (p->nums != nums) p = p->next; else { u = new Student;//改的地方 *u = *p; u->next = NULL; return u; } } return NULL; //原来有bug的: /* Student* p = this; Student* u = NULL; while (p != NULL) { if (p->nums != nums) p = p->next; else { u = p; u->next = NULL;//错在这里 return u; } } return NULL; */ } Student* Student::searchStu(string names) {//根据名字寻找学生 Student* p = this; Student* u = NULL; while (p != NULL) { if (p->nums != nums) p = p->next; else { u = new Student; *u = *p; u->next = NULL; return u; } } return NULL; /*Student* p = this; Student* u = new Student; while (p != NULL) { if (p->name != names) p = p->next; else { u = p; u->next = NULL; return u; } } return NULL;*/ } Student* Student::searchStuSex(string sex) {//根据性别寻找学生 Student* p = this; Student* temp = NULL, * head = NULL; Student* tNext = NULL; while (p != NULL) { if (p->sex == sex) {//找到相同性别,存下来 tNext = new Student; *tNext = *p; tNext->next = NULL; if (head == NULL) {//头节点为空 temp = tNext; head = temp; } else {//头节点非空 temp->next = tNext; temp = temp->next; } if(tNext!=NULL) tNext = tNext->next; } p = p->next; } if (head != NULL) return head; else return NULL; } Student* Student::searchStuAge(int age) {//根据年龄寻找学生 Student* head = NULL;//头节点 Student* p = this; Student* temp = NULL; Student* tNext = NULL; while (p != NULL) { if (p->age == age) {//找到相同年龄,存下来 tNext = new Student; *tNext = *p; tNext->next = NULL;//只留下此节点 if (head == NULL) {//头节点为空 temp = tNext; head = temp; } else {//头节点非空 temp->next = tNext; temp = temp->next; } if (tNext != NULL) tNext = tNext->next; } p = p->next; } if (head != NULL) return head; else return NULL; } Student* Student::searchStuClass(int classNum) {//根据班号寻找学生 Student* p = this; Student* temp = NULL, * head = NULL; Student* tNext = NULL; while (p != NULL) { if (p->classNum == classNum) { tNext = new Student; *tNext = *p; tNext->next = NULL; if (head == NULL) { temp = tNext; head = temp; } else { temp->next = tNext; temp = temp->next; } if (tNext != NULL) tNext = tNext->next; } p = p->next; } if (head != NULL) return head; else return NULL; } Student* Student::searchStuDepart(string Depart) {//根据系别寻找学生 Student* p = this; Student* temp = NULL, * head = NULL; Student* tNext = NULL; while (p != NULL) { if (p->department == Depart) { tNext = new Student; *tNext = *p; tNext->next = NULL; if (head == NULL) { temp = tNext; head = temp; } else { temp->next = tNext; temp = temp->next; } if (tNext != NULL) tNext = tNext->next; } p = p->next; } if (head != NULL) return head; else return NULL; } void Student::searchAll() {//控制寻找功能 cout << "1.按学号查询单个学生:\n"; cout << "2.按姓名查询单个学生\n"; cout << "3.按性别查询学生信息\n"; cout << "4.按班号查询学生信息\n"; cout << "请输入相应操作数:"; int u; cin >> u; int numS;//学号 string nameS;//姓名 string sexX;//性别 int numC;//班号 Student* p = NULL; switch (u) { case 1: cout << "输入学号:"; cin >> numS; judge1(numS); p = searchStu(numS); if (p != NULL)p->showMess(); else cout << "查无此人!请重新操作\n"; break; case 2: cout << "输入性名:"; cin >> nameS; judge4(nameS); p = searchStu(nameS); if (p != NULL)p->showMess(); else cout << "查无此人!请重新操作\n"; break; case 3: cout << "输入性别:"; cin >> sexX; judge3(sexX); p = searchStuSex(sexX); if (p != NULL)p->showMess(); else cout << "查无此人!请重新操作\n"; break; case 4: cout << "输入班号:"; cin >> numC; judge2(numC); p = searchStuClass(numC); if (p != NULL) p->showMess(); else cout << "查无此人!请重新操作\n"; break; default: break; } } bool Student::judgeNums(int num) {//学号为10位,除以10九次,余数在1-9范围内 for (int i = 1; i <= 9; i++) num /= 10; if (num == 0 || num > 10) return false; else return true; } bool Student::judgeClass(int num) {//判断班号是否超界 if (num >= 1 && num <= 200) return true; else return false; } bool Student::judgeSex(string u) {//判断性别格式是否符合 if (u == "男" || u == "女")return true; else return false; } bool Student::judgeName(string& inStr) {//判断姓名格式是否符合 unsigned char* str = (unsigned char*)inStr.c_str(); size_t length = inStr.length(); bool t = true; for (size_t i = 0; i < length; ++i) { if (str[i] > 160) t = true; if (inStr[i]>=0 && inStr[i]<=127) { t = false; break; } } if (t) return true; else return false; } bool Student::judgeAge(int num) { if (num <= 30 && num >= 10) return true; else return false; } void Student::judge1(int num) {//对应judgeNums int times = 4; while (!judgeNums(nums) && times > 1) { cout << "学号格式错误," << "还剩" << (times - 1) << "次输入机会:"; cin >> nums; times--; } if (times == 1) { cout << "输入学号错误!\n"; system("pause"); exit(0); } else return; } void Student::judge2(int num) {//对应judgeClass int times = 4; while (!judgeClass(classNum) && times>1) { cout << "班号格式错误," << "还剩" << (times - 1) << "次输入机会:"; cin >> classNum; times--; } if (times == 1) { cout << "输入班号错误!\n"; system("pause"); exit(0); } } void Student::judge3(string u) {//对应judgeSex int times = 4; while (!judgeSex(sex) && times>1) { cout << "性别格式错误," << "还剩" << (times - 1) << "次输入机会:"; cin >> sex; times--; } if (times == 1) { cout << "输入性别错误!\n"; system("pause"); exit(0); } } void Student::judge4(string& inStr) {//对应judgeName int times = 4; while (!judgeName(name) && times > 1) { cout << "姓名格式错误," << "还剩" << (times - 1) << "次输入机会:"; cin >> name; times--; } if (times == 1) { cout << "输入姓名错误!\n"; system("pause"); exit(0); } } void Student::judge5(int num) {//对应judgeAge int times = 4; while (!judgeAge(age) && times > 1) { cout << "年龄输入错误," << "还剩" << (times - 1) << "次输入机会:"; cin >> age; times--; } if (times == 1) { cout << "输入年龄错误!\n"; system("pause"); exit(0); } } void Student::statisticsSex() {//统计性别 cout << "按性别统计学生人数:" << '\n'; Student* p = searchStuSex("男"); int numS=0; while (p != NULL) { p = p->next; numS++; } cout << "男生人数:" << numS << '\n'; cout << "女生人数:" << sizes-numS << '\n'; } void Student::statisticsClass() {//统计班号 int numC=0; Student* p = NULL; cout << "按班号统计学生人数:" << '\n'; for (int i = 1; i <= 200; i++) { numC = 0; if (CLNUM[i] != 0) { p = searchStuClass(i); while (p != NULL) { p = p->next; numC++; } cout << "班号:" << i << '\t' << "人数:" << numC << '\n'; } else continue; } } void Student::statisticsAge() {//统计年龄 int numA = 0; Student* p = NULL; cout << "按年龄统计学生人数:" << '\n'; for (int i = 1; i <= 30; i++) { numA = 0; if (AGE[i] != 0) { Student* p = searchStuAge(i); while (p != NULL) { p = p->next; numA++; } cout << "年龄:" << i << " \t" << "人数:" << numA << '\n'; } else continue; } } void Student::statisticsDepart() {//统计系别 int numD = 0; cout << "按系别统计学生人数:" << '\n'; for (int i = 0; i < departTypes; i++) { numD = 0; Student* p = searchStuDepart(DEPART[i]); while (p != NULL) { p = p->next; numD++; } cout << "系别:" << DEPART[i] << '\t' << "人数:" << numD << '\n'; } } void Student::statisticsAll() {//控制统计功能 cout << "1.根据性别统计人数:\n"; cout << "2.根据班号统计人数\n"; cout << "3.根据年龄统计人数\n"; cout << "4.根据系别统计人数\n"; cout << "请输入相应操作数:"; int u; cin >> u; switch (u) { case 1: statisticsSex(); break; case 2: statisticsClass(); break; case 3: statisticsAge(); break; case 4: statisticsDepart(); break; default: break; } } void Student::showMess() {//输出 Student* p = this; cout << setiosflags(ios::left) << "学号:" << "\t\t" << "姓名:" << "\t\t" << "性别:" << "\t\t" << "年龄:" << "\t\t" << "系别:" << "\t\t" << "专业:" << "\t\t" << "班号:" << '\n'; while (p != NULL) { p->showBasic(); p = p->next; } } void Student::showBasic() {//特定格式输出基本信息 cout << setw(16) << nums; cout << setw(16) << name; cout << setw(16) << sex; cout << setw(16) << age; cout << setw(16) << department; cout << setw(16) << majoy; cout << setw(16) << classNum; cout<< '\n'; } void Student::setBasicFile() {//从文件批量录入 Student* p = this; Student* pLast = NULL;//防止最后一个节点的next不为NULL ifstream instuf("学生信息.txt", ios::in); instuf.seekg(0, ios::beg);//指针指向文件头 instuf.peek(); if (instuf.eof()) cout << "文件为空!\n"; else {//cout << "依次读入学生的学号、姓名、性别、年龄、系、专业、班号:\n"; while (!instuf.eof()) { //这里不做容错的判断了 instuf >> p->nums; if (!judgeNums(p->nums))break; instuf >> p->name; instuf >> p->sex; instuf >> p->age >> p->department >> p->majoy; instuf >> p->classNum; sizes++; CLNUM[p->classNum]++; AGE[p->age]++; int i = 0; while (i < departTypes) { if (DEPART[i] == p->department) break; i++; } if (i == departTypes) { DEPART[i] = p->department; departTypes++; } p->next = new Student; pLast = p; p = p->next; } } if (pLast != NULL) pLast->next = NULL; } void Student::writeF(ofstream& ofs) {//输出到文件中 Student* p = this; if (p == NULL) { cout << "没有数据! 请重新操作\n"; return; } ofs << nums << ' ' << name << ' ' << sex << ' ' << age << ' ' << department << ' ' << majoy << ' ' << classNum << '\n'; }

    ManagerStu类:

    //ManagerStu.h #pragma once #include"Student.h" class ManagerStu { public: void start();//总开关 void outScreen();//显示菜单 void out();//退出 void oper();//操作 void writeFile();//保存在文件中 Student* readFile();//从文件中读取 private: Student* head = NULL; }; //ManagerStu.cpp #include"ManagerStu.h" void ManagerStu::start() { this->outScreen(); this->oper(); } void ManagerStu::outScreen() { cout << "---------------------------------------------------------\n"; cout << "\n\n"; cout << " 学校学籍管理系统\n"; cout << " 实现功能:\n\n"; cout << " 1.录入 2.批量录入\n"; cout << " 3.删除 4.修改 5.查询 \n"; cout << " 6.所有信息分类统计 \n"; cout << " 7.输出所有学生信息\n"; cout << " 8.保存在文件中 \n\n"; cout << " 0.退出 \n"; cout << "\n\n"; cout << "---------------------------------------------------------\n"; } void ManagerStu::out() { exit(0); } void ManagerStu::oper() { cout << "输入数字做相应操作:"; char t;//操作数 int u;//无固定用处 Student* p=NULL; Student* pNext = NULL;//用来防止最后一个节点的next不为NULL head = p; Student* temp = head; while (cin>>t) { if(!(t <= '9' && t >= '0')){ cout << "无此操作数!请重新输入(退出输入0):\n"; cin >> t; if (t == '0') out(); } else { switch (t) { case '1': pNext = new Student; pNext->setBasic(); if (p == NULL) { p = pNext; head = p; } else { p->next = pNext; p = p->next; } pNext = pNext->next; break; case '2': p = readFile(); //下面用来接在已经录入的学生的后面 temp = head; while (temp != NULL && temp->next != NULL) temp = temp->next; if (temp == NULL) head = p; else temp->next = p; cout << "信息录入成功!\n"; while (p->next != NULL)p = p->next; break; case '3': head->showMess(); cout << "输入要删除成员的学号:"; cin >> u; head=head->delMessage(u); head->sizes--; cout << "删除后:\n"; head->showMess(); break; case '4': head->showMess(); head->changeStu(); cout << "修改后:\n"; head->showMess(); break; case '5': head->searchAll(); break; case '6': head->statisticsAll(); break; case '7': head->showMess(); break; case '8': writeFile(); cout << "信息保存成功!\n"; free(head); head->sizes = 0; head = NULL; break; case '0': exit(0); break; default: break; } } system("pause"); system("cls"); outScreen(); cout << "输入数字做相应操作,输入0则退出\n"; } } void ManagerStu::writeFile() { ofstream ofs; Student* p = head; ofs.open("学生信息.txt", ios::trunc); while (p != NULL) { p->writeF(ofs); p = p->next; } ofs.close(); } Student* ManagerStu::readFile() { Student* p = new Student; p->setBasicFile(); return p; }

    在做这玩意时,碰到最大的坑是,在按学号查找学生时原链表丢失了,导致花了好长时间找和改。

    Processed: 0.035, SQL: 9