#include #include #include #include #include #include #define COLLEGE_URL "colleges.txt" #define COLLEGE_NUMBER_URL "College_number.txt" #define MAJOR_URL "majors.txt" #define MAJOR_NUMBER_URL "Major_number.txt" #define ROOM_CHANGE_REQUESTS_URL "room_change_request.txt" #define ROOM_LEAVE_REQUESTS_URL "room_leave_request.txt" #define STUDENT_DATA_URL "Students_data.txt" #define STUDENT_NUMBER_URL "Student_number.txt" #define TEACHER_DATA_URL "Teachers_data.txt" #define TEACHER_NUMBER_URL "Teacher_number.txt" #define COURSE_NUMBER 4 #define INIT_CLASS_NUMBER 10 #define DIRECT_ID 114514 #define DIRECT_PASSWORD 1919810 #define REQUEST_URL "requests.txt" #define STUDENT_URL "students.txt" #define STUDENT_PASSWORD_URL "student_password.txt" #define TEACHER_PASSWORD_URL "teacher_password.txt" #define MONEY_URL "money.txt" #define BUS_RESERVE_COST 2 #define FACILITY_RESERVE_COST 5 #define P 10007 #define Q 10009//两个质数 #define E 65537 //密钥 与PHI(N)互质 #define N (P * Q) #define PHI ((P - 1) * (Q - 1)) #define D 35910881//D使得(E * D) % PHI = 1 #define BUS_ROUTE_ONE "南湖-浑南.txt" #define BUS_ROUTE_TWO "浑南-南湖.txt" #define TABLE_SIZE 10003 int INDEX = 1; typedef struct _Courses{ float credit; // 学分 char name[20]; // 课程名 }Course; typedef struct _Scores{ int Math; int English; int Computer; int Politics; }Scores; typedef struct _Student { int Class; // 四位数字 char gender[3]; int id; int dorm_index; // (6位数字:楼号+AB+寝室号+床位号) double money; double GPA; long long password; char name[10]; char major[20]; char college[23]; Scores scores; struct _Student *next; }Student; typedef struct _Teacher { char gender[3]; int id; int teaching_class; // 四位数字 long long password; char name[10]; char course[20]; char college[23]; struct _Teacher *next; }Teacher; typedef struct _Colleges{ int id; char college_name[23]; }Colleges; typedef struct _Major{ int college_id; // 存储该专业所属学院的编号 int id;//:1001/1000*1000 char name[23]; }Major; typedef struct TreeNode{ Student* student; struct TreeNode* left; struct TreeNode* right; }TreeNode; typedef struct _BusSchedule{ int index; char date[40]; // 班车日期 char time[40]; // 班车时间 }BusSchedule; typedef struct _siteSchedule{ char siteType[100]; // 场地类型 char date[100]; // 场地可预约日期 char time[100]; // 场地可预约时间 }siteSchedule; typedef struct _HashTable { Student* students[TABLE_SIZE]; }HashTable; //哈希表 int hashFunction(int id); HashTable* createHashTable(void); bool insertStudent(HashTable* table, Student* student); Student* findStudent(HashTable* table, int id); bool deleteStudent(HashTable* table, int id); bool freeHashTable(HashTable* table); //添加学院 void Admin_College(int* number); void Write_File_College_Number(int number); void Read_File_College_Number(int*number); Colleges* Read_College(int college_number); void Print_College(Colleges* colleges, int college_number); //添加专业 void Read_File_Major_Number(int *major_number); void Admin_Major(Colleges* colleges, int college_number,int* major_number); void Write_File_Major_Number(int number); Major* Read_Major(int major_number); //归并排序 int getCourseScore(Scores* scores, const char* courseName);// 根据课程名查找对应的成绩 int compareStudents(Student* s1, Student* s2, const char* courseName);// 比较函数:根据课程名排序 void merge(Student* array, int left, int mid, int right, const char* courseName);// 归并排序:合并两个排序好的子数组 void mergeSort(Student* array, int left, int right, const char* courseName);// 归并排序递归函数 ///二叉树添加并存储学生信息 TreeNode* insert(TreeNode* root, Student* student);//插入节点到二叉树 TreeNode* createBinaryTree(Student* students, int size);// 创建二叉树 void printInOrder(TreeNode* node);// 中序遍历打印二叉树 void freeTree(TreeNode* node);// 释放二叉树内存 TreeNode* find(TreeNode* root, int id);// 查找节点 void sortByCourseScore(Student* students, int size, const char* courseName);// 输出按指定项目成绩排序的学生信息 bool select_college(Colleges* colleges,int college_number,char* college);//在给定学院中选择学院和专业 bool select_major(Colleges* colleges,int college_number,Major* majors,int major_number,char* college,char* major); void Read_File_Student_Number(int* student_number);//读取先前的学生数量 //初始化学生,并存进文件 void inputStudentInfo(Colleges* colleges,int college_number,Major* majors,int major_number,int* student_number); void Write_File_Student_Number(int student_number);//更新学生数量 Student* Read_Students(int student_number);//从文件中读取到最新的Students数组 void Undefined_Inital_Stu(Student* students,int student_number); void Read_File_Teacher_Number(int* teacher_number);//读取先前的教师数量 //初始化教师,并存进文件 void inputTeacherInfo(Colleges* colleges,Course courses[],int college_number,int* teacher_number); void Write_File_Teacher_Number(int teacher_number);//更新教师数量 Teacher* Read_Teachers(int teacher_number);//从文件中读取到最新的Teachers数组 //初始化密码 void Inital_password(Student* students,int student_number,Teacher* teachers,int teacher_number); //教师登录 bool Teacher_Login(Teacher* teachers,Teacher *target_teacher,int teacher_number); //教师录入成绩 void Teacher_Import_Grade(Student*students,int student_number,Teacher *teacher,int teacher_number,Course courses[]); //计算某个学生当前总GPA double Total_GPA_Calculation(Student* student,Course courses[],int student_number); //更新某个学生的GPA void Update_GPA(Student* student,Course courses[], int student_number); //学生查看成绩和GPA void Student_Watch_Grade(Student* student); //分配寝室号 void assignDormitory(Student* students, int numStudents); bool Student_Login(Student* students,Student *target_student,int student_number); //读取学生成绩文件 void Students_Read_Grade_File(TreeNode* root,int student_number); //取模运算 //参数 底数,指数,模 // 先对底数取模缩小 再对指数缩小 直到指数为0 long long quick_pow(long long base, long long power, long long mod); // 加密函数 long long encrypt(long long original_password); // 解密函数 long long decrypt(long long ciphertext); void Read_Password(Student*students,int student_number,Teacher*teachers,int teacher_number,TreeNode* root); //余额系统 void Read_Money(Student*students,int student_number,Teacher*teachers,int teacher_number,TreeNode* root); void Moneys_System(Student* student,int student_number,BusSchedule*b1,BusSchedule*b2,int bn1,int bn2); //班车管理 void inputBusSchedule(BusSchedule *schedule); void saveBusScheduleToFile(const BusSchedule *schedule,const char *filename,int counter); int Counter(const char *filename); BusSchedule* Print_Bus_Conditions(const char *filename); //场地管理 void inputSiteSchedule(siteSchedule *schedule); void saveSiteScheduleToFile(const siteSchedule *schedule,const char *filename,int counter); int main() { //主函数入口 int college_number = 0; bool first=false; int major_number = 0; Colleges* colleges; Major* majors; BusSchedule *bus_schedule1; BusSchedule *bus_schedule2; BusSchedule schedule; int student_number=0; Student* students; int teacher_number=0; Teacher* teachers; TreeNode* root; Student target_student; target_student.money=48.0; //假定只有4门课程,分别为:Math, English, Computer,Politics Course courses[]={{5,"Math"}, {3.5,"English"},{3,"Computer"},{3,"Politics"}}; //登录系统 printf("欢迎进入聪明东大\n"); Sleep(2000); system("cls"); start: printf("首次自动进入管理员端登陆系统:\n1.设置学院与专业模板\n2.添加学生和教师信息\n3.设置班车场次\n\n" "按1进入教师端登录系统:\n1.录入成绩\n2.查询成绩\n3.修改成绩\n4.修改密码\n5.展示成绩\n6.退出登录\n\n" "按2进入学生端登录系统:\n1.课程成绩\n2.宿舍情况\n3.余额与预约系统\n4.修改密码\n5.退出系统\n\n" "按3进入导员端登陆系统\n1.处理校外住宿申请\n\n按4退出系统\n\n"); www: printf("建议测试顺序:01234,首次选择自动进行管理员初始化,:"); int login_choice; if(!first) { system("pause"); system("cls"); printf("进入管理员端登陆系统(处于测试目的此处不再设置密码)\n"); printf(("1.设置学院与专业模板\n2.添加学生和教师信息\n3.设置班车场次\n")); printf("由于管理员系统的特殊性,需要依次对以上项目进行初始化\n"); //管理员初始化设置学生的学院与专业模板 //先读取已存在学院的数量,再添加学院 //把添加的学院数量与原有学院数量相加,得到学院总数,并存入文件 printf("进入学院与专业模板设置\n"); system("pause"); system("cls"); printf("1.设置学院名\n"); printf("请输入学院名(每输入一个学院按一次回车键,输入Ctrl+Z停止输入):\n"); Read_File_College_Number(&college_number); Admin_College(&college_number); Write_File_College_Number(college_number); //把学院存入数组,供日后学生信息设置选择 colleges = Read_College(college_number); printf("学院设置结束\n"); Sleep(500); system("cls"); printf("管理员系统:2.设置专业名\n"); Print_College(colleges,college_number); printf("请输入学院id与专业名称(按回车输入下一个,按Ctrl+Z停止输入):\n"); Read_File_Major_Number(&major_number); Admin_Major(colleges,college_number,&major_number); Write_File_Major_Number(major_number); //把专业存入数组,供日后学生信息设置选择 majors = Read_Major(major_number); printf("专业设置结束\n"); Sleep(500); system("cls"); Sleep(500); printf("开始进行人员信息添加\n"); Sleep(1000); system("cls"); //学生基本信息处理 Read_File_Student_Number(&student_number); inputStudentInfo(colleges,college_number,majors,major_number,&student_number); Write_File_Student_Number(student_number); Sleep(500); system("cls"); Sleep(500); //教师基本信息处理 Read_File_Teacher_Number(&teacher_number); inputTeacherInfo(colleges,courses,college_number,&teacher_number); Write_File_Teacher_Number(teacher_number); students = Read_Students(student_number); Undefined_Inital_Stu(students,student_number); assignDormitory(students,student_number); teachers = Read_Teachers(teacher_number); //初始化栈内密码 Inital_password(students,student_number,teachers,teacher_number); //基础信息设置结束 Sleep(500); system("cls"); Sleep(500); // 创建二叉树 root = createBinaryTree(students,student_number); //读取曾经手动设置过的密码 Read_Password(students,student_number,teachers,teacher_number,root); //读取成绩文件信息 Students_Read_Grade_File(root,student_number); Read_Money(students,student_number,teachers,teacher_number,root); printf("进入班车设置\n"); //班车管理 int choice_buses; printf("南湖 --> 浑南:\n"); bus_schedule1=Print_Bus_Conditions(BUS_ROUTE_ONE); printf("浑南 --> 南湖:\n"); bus_schedule2=Print_Bus_Conditions(BUS_ROUTE_TWO); while (true) { printf("下面进入班车设置:\n"); printf("1. 南湖 --> 浑南\n"); printf("2. 浑南 --> 南湖\n"); printf("3. 退出\n"); printf("请输入选择的序号:"); scanf("%d",&choice_buses); if (choice_buses==3) { break; } if(choice_buses==1) { inputBusSchedule(&schedule); int NanhuCounter=Counter(BUS_ROUTE_ONE)+1; saveBusScheduleToFile(&schedule,BUS_ROUTE_ONE,NanhuCounter); Sleep(1000); system("cls"); } else if(choice_buses==2) { inputBusSchedule(&schedule); int HunnanCounter=Counter(BUS_ROUTE_TWO)+1; saveBusScheduleToFile(&schedule,BUS_ROUTE_TWO,HunnanCounter); Sleep(1000); system("cls"); } else { printf("无效的选择,请重新输入。\n"); Sleep(1000); system("cls"); } } first=true; Sleep(1000); system("cls"); goto start; } scanf("%d",&login_choice); system("cls"); switch(login_choice) { case 1: //教师登录 printf("进入教师端登录系统\n"); Teacher target_teacher; if(Teacher_Login(teachers,&target_teacher,teacher_number)) { //载入教师信息 printf("工号:%08d\n姓名:%s\n性别:%s\n所属学院:%s\n教学课程:%s\n授课班级:%d\n", target_teacher.id,target_teacher.name,target_teacher.gender, target_teacher.college,target_teacher.course,target_teacher.teaching_class); system("pause"); system("cls"); asd: printf("请选择:\n1.录入成绩\n2.查询成绩\n3.修改成绩\n4.修改密码\n5.展示成绩\n6.退出登录\n"); int bb; scanf("%d",&bb); if(bb==1) { //教师录入成绩 bool jutice = true; while(true) { printf("请问是否进行%d班的%s成绩录入(1或0):",target_teacher.teaching_class,target_teacher.course); int choice_grade_enter; scanf("%d",&choice_grade_enter); if(choice_grade_enter==0) { jutice=false; break; } else if(choice_grade_enter==1) { jutice=true; break; } else { printf("\n输入错误!请重新输入!\n"); continue; } } system("cls"); if(jutice) { printf("学生成绩管理系统加载中......\n"); Sleep(1000); printf("下面进行您所教班级的学生成绩录入......\n"); Sleep(2000); system("cls"); //创建课程文件,用于存储学生成绩 //文件名格式为:课程名班级.txt(如Math2405.txt) //存储成绩格式为:学生ID(空格)成绩(换行) Teacher_Import_Grade(students,student_number,&target_teacher,teacher_number,courses); //停止录入成绩 } } else if(bb==2) { //教师查询成绩 printf("学生成绩管理系统加载中......\n"); Sleep(1000); printf("下面进行您所教班级的学生成绩查询......\n"); Sleep(2000); system("cls"); printf("请输入要查询成绩的学生ID:"); //读取students数组中对应班级的学生成绩 int to_find_student_id; scanf("%d",&to_find_student_id); TreeNode* target_student = find(root,to_find_student_id); if(target_student!=NULL) { Student_Watch_Grade(target_student->student); } } else if(bb==3) { //教师修改成绩 printf("学生成绩管理系统加载中......\n"); Sleep(1000); printf("下面进行您所教班级的学生成绩修改......\n"); Sleep(2000); system("cls"); //读取students数组中对应班级的学生成绩 printf("请输入要修改成绩的学生ID:"); int to_find_student_id; scanf("%d",&to_find_student_id); TreeNode* target_student = find(root,to_find_student_id); if(target_student!=NULL) { char temp_course_url[30]; sprintf(temp_course_url,"%s.txt",target_teacher.course); //打开/创建成绩文件,文件名格式为:教工号课程名班级号.txt,如:Math.txt //数据存储格式:学号加空格加成绩,如:20245738 90 FILE* fp = fopen(temp_course_url,"a+"); if(fp==NULL) { printf("文件打开失败!\n"); return 0; } printf("请输入修改后的成绩:"); int grade_to_change; scanf("%d",&grade_to_change); //修改成绩 fprintf(fp,"%s %d\n",to_find_student_id,grade_to_change); fclose(fp); printf("成绩修改成功!\n"); Sleep(2000); system("cls"); } else { printf("未找到该学生!\n"); Sleep(2000); system("cls"); } } else if(bb==4) { int time_count=0; //密码错误次数 //修改教师密码 password_enter: printf("请输入修改前的密码:"); long long former_password; scanf("%lld",&former_password); if(former_password==target_teacher.password) { printf("请输入修改后的密码:"); long long new_password; scanf("%lld",&new_password); target_teacher.password = new_password; //把密码加密后存进入文件 FILE* fTeacher= fopen(TEACHER_PASSWORD_URL,"a+"); fprintf(fTeacher,"%s %lld\n",target_teacher.id,encrypt(target_teacher.password)); fclose(fTeacher); printf("密码修改成功!\n"); Sleep(2000); system("cls"); } else { printf("密码错误!\n"); time_count++; //判断是否继续输入密码 if(time_count>3) { printf("密码错误次数过多!\n"); Sleep(2000); system("cls"); goto choice_one; } jjj: int a; printf("是否继续输入密码?(1或0):"); scanf("%d",&a); if(a==1) { goto password_enter; } else if(a==0) { system("cls"); } else { printf("输入错误!请重新输入!\n"); goto jjj; } } } else if(bb==5) { printf("请问是否进行排序?是请按1,不是请按0:"); int choice_sort; scanf("%d",&choice_sort); if(choice_sort==1) { // 按照某项成绩排序并输出 Sleep(500); system("cls"); printf("下面进行排序\n可排序的项目:\nMath\nEnglish\nComputer\nPolitics\n"); printf("GPA\nid\nClass\n请选择你要排序的项目:"); char choices[20]; scanf("%s",choices); while(true) { if(strcmp(choices,"Math")!=0&&strcmp(choices,"English")!=0&&strcmp(choices,"Computer")!=0&&strcmp(choices,"Politics")!=0&&strcmp(choices,"GPA")!=0&&strcmp(choices,"id")!=0&&strcmp(choices,"Class")!=0) { printf("输入错误!请重新输入:"); continue; } else { break; } } printf("请选择降序(1)或升序(-1):"); while(true) { int order; scanf("%d",&order); Sleep(500); system("cls"); if(order==1||order==(-1)) { INDEX=order; sortByCourseScore(students,student_number,choices); INDEX=1; //还原 break; } else { printf("输入错误!请重新输入:"); continue; } } } else if(choice_sort==0) { printf("退出排序!\n"); Sleep(2000); system("cls"); } else { printf("输入错误!请重新输入!"); Sleep(2000); system("cls"); goto choice_start; } } else if(bb==6) { //退出系统 printf("退出系统成功!\n"); Sleep(2000); system("cls"); } else { printf("输入错误!请重新输入!\n"); goto asd; } int a1; choice_one: printf("请输入是否继续?(1或0):"); scanf("%d",&a1); if(a1==1) { system("cls"); goto start; } else if(a1==0) { system("cls"); } else { printf("输入错误!请重新输入!\n"); goto choice_one; } break; case 2: //学生登录 printf("进入学生端登录系统\n"); if(Student_Login(students,&target_student,student_number)) { //载入学生信息 printf("学号:%08d\n姓名:%s\n性别:%s\n所属学院:%s\n所学专业:%s\n所属班级:%d\n", target_student.id,target_student.name,target_student.gender, target_student.college,target_student.major,target_student.Class); system("pause"); system("cls"); ggg: printf("1.课程成绩\n2.宿舍情况\n3.余额与预约系统\n4.修改密码\n5.退出系统\n"); printf("请选择你要查看的内容:"); //学生查看成绩 int op; scanf("%d",&op); if(op==1) { printf("学生成绩系统加载中......\n"); Sleep(1000); printf("下面进行您所修课程的成绩查询......\n"); Sleep(2000); system("cls"); //读取课程文件,输出成绩 Student_Watch_Grade(&target_student); system("pause"); } else if(op==2) { //a*100000+ b*10000+c*1000+d*10+e // 21 int location = target_student.dorm_index; int bed = location%10; location/=10; int area = location%1000; location/=1000; int AB = location%10; char ab; if(AB==1) ab='A'; else if(AB==2) ab='B'; int buliding = location/10; printf("宿舍位置:%d舍 %c%d %d号床\n",buliding,ab,area,bed); ops: printf("请问你是否需要申请校外住宿,(1.需要申请 2.不需要申请):"); int opt; scanf("%d",&opt); if(opt==1) { FILE* Out_live=fopen(ROOM_CHANGE_REQUESTS_URL,"a+"); rewind(Out_live); //查找是否提交过,回复过 int stud_id; char reason[50]; char answer[10]; int result; bool whether_find=false; bool whether_reply=false; while ((result = fscanf(Out_live,"%d %s %s",&stud_id,reason,answer))==3) { if(stud_id==target_student.id) { whether_find=true; size_t len=strcspn(answer, "\n"); // 找到换行符的位置 answer[len]='\0'; // 在换行符位置终止字符串 if (strcmp(answer,"IamML")!=0) { // 已提交,已回复 whether_reply = true; } break; } } if (whether_find) { if (whether_reply) { printf("Has been replied, please check\n"); } else { printf("Has been submitted, but no answer yet, please wait\n"); } } else { printf("Hasn't submit\n"); char reasons[50]; printf("请输入你的理由(20字以内):"); scanf("%s", reasons); fprintf(Out_live, "%d %s IamML\n", target_student.id, reasons); printf("提交成功!请等待反馈\n"); } fclose(Out_live); } else if(opt==2) { printf("退出申请\n"); } else if(opt!=1&&opt!=2) { printf("输入错误,请重新输入\n"); goto ops; } } else if(op==3) { //余额系统 printf("学生余额系统加载中......\n"); Sleep(1000); system("pause"); system("cls"); int bn1 = Counter(BUS_ROUTE_ONE); int bn2 = Counter(BUS_ROUTE_TWO); Moneys_System(&target_student,student_number,bus_schedule1,bus_schedule2,bn1,bn2); } else if(op==4) { int time_count=0; //密码错误次数 //修改学生密码 password_enter1: printf("请输入修改前的密码:"); long long former_password; scanf("%lld",&former_password); if(former_password==target_student.password) { printf("请输入修改后的密码:"); long long new_password; scanf("%lld",&new_password); target_student.password = new_password; //把密码加密后存进入文件 FILE* fStudent= fopen(STUDENT_PASSWORD_URL,"a+"); fprintf(fStudent,"%s %lld\n",target_student.id,encrypt(target_student.password)); fclose(fStudent); printf("密码修改成功!\n"); Sleep(2000); system("cls"); } else { printf("密码错误!\n"); time_count++; //判断是否继续输入密码 if(time_count>3) { printf("密码错误次数过多!\n"); Sleep(2000); system("cls"); goto choice_two; } jjj1: int b; printf("是否继续输入密码?(1或0):"); scanf("%d",&b); if(b==1) { goto password_enter1; } else if(b==0) { system("cls"); } else { printf("输入错误!请重新输入!\n"); goto jjj1; } } } else if(op==5) { printf("退出登录!\n"); Sleep(2000); system("cls"); } else { printf("输入错误!请重新输入!\n"); goto ggg; } } choice_two: int a2; printf("请输入是否继续?(1或0):"); scanf("%d",&a2); if(a2==1) { system("cls"); goto start; } else if(a2==0) { system("cls"); } else { printf("输入错误!请重新输入!\n"); goto choice_two; } break; case 3: //导员登录 printf("进入导员端登录系统(以下处于测试目的直接给出了账号密码,请按照其输入)\n"); printf("请输入工号(114514):"); int Direct_id; long long Direct_password; scanf("%d",&Direct_id); printf("请输入密码(1919810):"); scanf("%lld",&Direct_password); if(Direct_id==DIRECT_ID&&Direct_password==DIRECT_PASSWORD) { printf("登录成功!\n"); Sleep(2000); system("cls"); printf("下面进入宿舍管理..."); Sleep(2000); system("cls"); printf("1.校外住宿处理 2.退出页面\n"); printf("请选择你要处理的内容:"); int op3; tar: scanf("%d",&op3); if(op3==1) { int student_id; char reason[50]; char reply[50]; int result; int choice1; FILE* fp = fopen(ROOM_CHANGE_REQUESTS_URL,"r+"); FILE *temp_fp = fopen("temp.txt","a+"); printf("以下为未处理的学生宿舍申请:\n"); while(fscanf(fp,"%d %s %s",&student_id,reason,reply)==3)//判定是否已经到文件结尾 { if(strcmp(reply,"IamML")!=0) { continue; } else { //导员端未对申请进行过处理,则进行处理 printf("学号:%d 原因:%s\n",student_id,reason); do{ printf("是否同意ta走读?(是:1 ,否:0):"); scanf("%d",&choice1); if(!(choice1==0 || choice1==1)) { printf("输入有误,请重新输入\n"); } else if(choice1==1) { strcpy(reply,"同意"); fprintf(temp_fp,"%d %s %s\n",student_id,reason,reply); } else { strcpy(reply,"不同意"); fprintf(temp_fp,"%d %s %s\n",student_id,reason,reply); } }while(choice1!=0 && choice1!=1); } } fclose(fp); fclose(temp_fp); remove(ROOM_CHANGE_REQUESTS_URL); rename("temp.txt",ROOM_CHANGE_REQUESTS_URL); } else if (op3==2) { printf("退出系统\n"); } else { printf("输入错误!请重新输入:\n"); goto tar; } } choice_three: int a3; printf("请输入是否继续?(1或0):"); scanf("%d",&a3); if(a3==1) { system("cls"); goto start; } else if(a3==0) { system("cls"); } else { printf("输入错误!请重新输入!\n"); goto choice_three; } case 4: printf("退出系统\n"); break; } } choice_start: printf("为了展示排序内容,故将排序算法独立出来展示\n"); printf("请问是否进行排序?是请按1,不是请按0:"); int choice_sort; scanf("%d",&choice_sort); if(choice_sort==1) { // 按照某项成绩排序并输出 Sleep(500); system("cls"); printf("下面进行排序\n可排序的项目:\nMath\nEnglish\nComputer\nPolitics\n"); printf("GPA\nid\nClass\n请选择你要排序的项目:"); char choices[20]; scanf("%s",choices); while(true) { if(strcmp(choices,"Math")!=0&&strcmp(choices,"English")!=0&&strcmp(choices,"Computer")!=0&&strcmp(choices,"Politics")!=0&&strcmp(choices,"GPA")!=0&&strcmp(choices,"id")!=0&&strcmp(choices,"Class")!=0) { printf("输入错误!请重新输入:"); continue; } else { break; } } printf("请选择降序(1)或升序(-1):"); while(true) { int order; scanf("%d",&order); Sleep(500); system("cls"); if(order==1||order==(-1)) { INDEX=order; sortByCourseScore(students,student_number,choices); INDEX=1; //还原 break; } else { printf("输入错误!请重新输入:"); continue; } } } else if(choice_sort==0) { printf("退出排序!\n"); Sleep(2000); system("cls"); } else { printf("输入错误!请重新输入!"); Sleep(2000); system("cls"); goto choice_start; } // 查找节点 // int searchId = 1002; // TreeNode* result = find(root, searchId); // if (result!=NULL) // { // printf("\n找到ID为%d的学生,姓名为:%s\n", searchId, result->student->name); // } // else // { // printf("\n未找到ID为%d的学生\n", searchId); // } // 释放二叉树内存 freeTree(root); free(students); free(teachers); free(colleges); free(majors); system("pause"); return 0; } //子函数 //管理员输入学院名并加编号,把信息存储在 "colleges.txt",若无, 则创建文件 //打开文件->判断是否是错误输入->以"%d %s\n"形式写进COLLEGE_URL文件->更新college_number //输入number(),无返回值 //应该在外部定义什么变量 //应该在开头输出printf(" "); void Admin_College(int* number) { int college_number=*number+1; FILE *college_file=fopen(COLLEGE_URL,"a+"); char college_name[25]; while (scanf("%s",college_name)==1) { int has_digit=0; for (int i=0;iscores.Math; } else if (strcmp(courseName, "English") == 0) { return student->scores.English; } else if (strcmp(courseName, "Computer") == 0) { return student->scores.Computer; } else if (strcmp(courseName, "Politics") == 0) { return student->scores.Politics; } else if (strcmp(courseName,"GPA")==0) { return student->GPA; } else if (strcmp(courseName,"id")==0) { return student->id; } else if (strcmp(courseName,"Class")==0) { return student->Class; } return -1; // 如果没有找到匹配的课程,返回一个无效值 } // 比较函数:根据课程名排序 int compareStudents(Student* student1, Student* student2, const char* courseName) { // 获取指定课程的成绩 int score1 = getCourseScore(student1, courseName); int score2 = getCourseScore(student2, courseName); // 如果没有找到课程的成绩,返回0(可以根据需求修改) if (score1 == -1 && score2 == -1) { return 0; } if (score1 == -1) return INDEX; // student1 排后 if (score2 == -1) return -1*INDEX; // student2 排后 // 按成绩排序 if (score1 < score2) { return INDEX; } else if (score1 > score2) { return (-1)*INDEX; } return 0; // 如果成绩相等,返回0 } // 归并排序:合并两个排序好的子数组 void merge(Student* array, int left, int mid, int right, const char* courseName) { int n1 = mid - left + 1; int n2 = right - mid; // 临时数组 Student* leftArray = (Student*)malloc(n1 * sizeof(Student)); Student* rightArray = (Student*)malloc(n2 * sizeof(Student)); for (int i = 0; i < n1; i++) { leftArray[i] = array[left + i]; } for (int j = 0; j < n2; j++) { rightArray[j] = array[mid + 1 + j]; } int i=0, j=0, k=left; // 合并两个子数组 while (istudent = student; newNode->left = NULL; newNode->right = NULL; return newNode; } if (student->id < root->student->id) { root->left = insert(root->left, student); } else { root->right = insert(root->right, student); } return root; } // 创建二叉树 TreeNode* createBinaryTree(Student* students, int size) { TreeNode* root = NULL; for (int i = 0; i < size; i++) { root = insert(root, &students[i]); } return root; } // 中序遍历打印二叉树 void printInOrder(TreeNode* node) { if (node != NULL) { printInOrder(node->left); printf("ID: %d, Name: %s, Money: %.2f\n", node->student->id, node->student->name, node->student->money); printInOrder(node->right); } } // 释放二叉树内存 void freeTree(TreeNode* node) { if (node != NULL) { freeTree(node->left); freeTree(node->right); free(node); } } // 查找节点 TreeNode* find(TreeNode* root, int id) { if (root == NULL || root->student->id == id) { return root; } if (id < root->student->id) { return find(root->left, id); } else { return find(root->right, id); } } // 输出按指定课程成绩排序的学生信息 void sortByCourseScore(Student* students, int size, const char* courseName) { // 归并排序:按指定课程成绩排序 mergeSort(students,0,size-1,courseName); // 打印排序后的学生信息 printf("\n按%s成绩排序后的学生信息(-1表示信息未录入):\n",courseName); for (int i=0;i=1000 && class_id<=9999) { students[i].Class = class_id; break; } else { printf("输入错误,请重新输入:"); } } //账户金额初始化 students[i].money = 0; // 密码设置:默认密码为学号 students[i].password = students[i].id; FILE* fp = fopen(STUDENT_DATA_URL,"a+"); if(fp) { fprintf(fp,"%d %s %s %s %s %d\n",students[i].id,students[i].name,students[i].gender, students[i].college,students[i].major,students[i].Class); } fclose(fp); free(students); } } //更新学生数量 void Write_File_Student_Number(int student_number) { FILE *fp = fopen(STUDENT_NUMBER_URL, "w"); if(fp) { fprintf(fp,"%d",student_number); } fclose(fp); } //从文件中读取到最新的Students数组 Student* Read_Students(int student_number) { Student* students = (Student*)malloc(sizeof(Student)*(student_number+1)); FILE* fp = fopen(STUDENT_DATA_URL,"r"); if(fp) { for(int i=0;i0) teachers = (Teacher*)malloc(sizeof(Teacher) * n); for (int i=0;i=1000 && teachers[i].teaching_class<=9999) { break; } else { printf("输入错误,请重新输入:"); } } //密码设置:默认密码为教工号 teachers[i].password = teachers[i].id; FILE* fp = fopen(TEACHER_DATA_URL,"a+"); if(fp) { fprintf(fp,"%d %s %s %s %s %d\n",teachers[i].id,teachers[i].name,teachers[i].gender, teachers[i].college,teachers[i].course,teachers[i].teaching_class); } fclose(fp); } if(teachers!=NULL) free(teachers); } //更新教师数量 void Write_File_Teacher_Number(int teacher_number) { FILE *fp = fopen(TEACHER_NUMBER_URL, "w"); if(fp) { fprintf(fp,"%d",teacher_number); } } //从文件中读取到最新的Teachers数组 Teacher* Read_Teachers(int teacher_number) { Teacher* teachers = (Teacher*)malloc(sizeof(Teacher)*(teacher_number+1)); FILE* fp = fopen(TEACHER_DATA_URL,"r"); if(fp) { for(int i=0;icourse); //打开/创建成绩文件,文件名格式为:教工号课程名班级号.txt,如:Math.txt //数据存储格式:学号加空格加成绩,如:20245738 90 FILE* fp = fopen(temp_course_url,"a+"); for(int i=0;iteaching_class) { if(strcmp(teacher->course,"Math")==0) { if(students[i].scores.Math == (-1)) { printf("%d %s 的 高等数学 成绩为:",students[i].id,students[i].name); scanf("%d",&students[i].scores.Math); fprintf(fp,"%d %d\n",students[i].id,students[i].scores.Math); } else continue; } else if(strcmp(teacher->course,"Politics")==0) { if(students[i].scores.Politics == (-1)) { printf("%d %s 的 思想道德与法治 成绩为:",students[i].id,students[i].name); scanf("%d",&students[i].scores.Politics); fprintf(fp,"%d %d\n",students[i].id,students[i].scores.Politics); } else continue; } else if(strcmp(teacher->course,"English")==0) { if(students[i].scores.English == (-1)) { printf("%d %s 的 大学英语 成绩为:",students[i].id,students[i].name); scanf("%d",&students[i].scores.English); fprintf(fp,"%d %d\n",students[i].id,students[i].scores.English); } else continue; } else if(strcmp(teacher->course,"Computer")==0) { if(students[i].scores.Computer == (-1)) { printf("%d %s 的 程序设计基础 成绩为:",students[i].id,students[i].name); scanf("%d",&students[i].scores.Computer); fprintf(fp,"%d %d\n",students[i].id,students[i].scores.Computer); } else continue; } Update_GPA(&students[i],courses,student_number); } } fclose(fp); printf("成绩录入成功\n"); } //计算学生的总GPA double Total_GPA_Calculation(Student* student,Course courses[],int student_number) { double total_credit = 0; // 学分总和 //学科成绩如果是-1,则表示该学生没有选该课程,不计算学分 total_credit+=(student->scores.Math!=(-1)?courses[0].credit:0); total_credit+=(student->scores.English!=(-1)?courses[1].credit:0); total_credit+=(student->scores.Computer!=(-1)?courses[2].credit:0); total_credit+=(student->scores.Politics!=(-1)?courses[3].credit:0); if(total_credit==0) return 0; double total_grade = 0;// 总成绩 total_grade+=courses[0].credit*(student->scores.Math>=60?(student->scores.Math/10.0-5):0); total_grade+=courses[1].credit*(student->scores.English>=60?(student->scores.English/10.0-5):0); total_grade+=courses[2].credit*(student->scores.Computer>=60?(student->scores.Computer/10.0-5):0); total_grade+=courses[3].credit*(student->scores.Politics>=60?(student->scores.Politics/10.0-5):0); if(total_grade==0) return 0; return total_grade/total_credit; } void Inital_password(Student* students,int student_number,Teacher* teachers,int teacher_number) { for(int i=0;iGPA = temp_GPA; } // for循环->以“%d\n”形式输出->存到结构体( students.dorm_index) //输入 numStudents(学生人数) //Student结构体 void assignDormitory(Student *students, int numStudents) { int index=0; for(int a=1;a<=6;a++)//楼号 { for(int b=1;b<=2;b++)//1是A区,2是B区 { for(int c=1;c<=6;c++)//楼层数 { for(int d=1;d<=35;d++)//房间号 { for(int e=1;e<=4;e++)//床位 { if(index>=numStudents) return; students[index].dorm_index=a*100000+ b*10000+c*1000+d*10+e; //生成寝室号 // printf("%d\n",students[index].dorm_index); index++; } } } } } } bool Student_Login(Student* students,Student *target_student,int student_number) { int count = 0; printf("你只有三次机会,请谨慎输入账号密码(初始密码为学号)(由于测试直接给出账号:20245865):\n"); while(true) { if(count==3) { printf("输入错误次数过多,请稍后再试!\n"); return false; } int id; printf("请输入8位学号:"); scanf("%d",&id); long long password; printf("请输入密码(初始密码为学号):"); scanf("%lld",&password); for(int i=0;istudent->scores.Math = temp_score; } } fclose(fMath); } status=0; FILE* fEnglish = fopen("English.txt", "r"); if(fEnglish!=NULL) { while((status = fscanf(fEnglish, "%d %d", &temp_id, &temp_score))!=EOF && status==2) { TreeNode* result = find(root, temp_id); if (result!=NULL) { result->student->scores.English = temp_score; } } fclose(fEnglish); } status=0; FILE* fComputer = fopen("Computer.txt", "r"); if(fComputer!=NULL) { while((status = fscanf(fComputer, "%d %d", &temp_id, &temp_score))!=EOF && status==2) { TreeNode* result = find(root, temp_id); if (result!=NULL) { result->student->scores.Computer = temp_score; } } fclose(fComputer); } status=0; FILE* fPolitics = fopen("Politics.txt", "r"); if(fPolitics!=NULL) { while((status = fscanf(fPolitics, "%d %d", &temp_id, &temp_score))!=EOF && status==2) { TreeNode* result = find(root, temp_id); if (result!=NULL) { result->student->scores.Politics = temp_score; } } fclose(fPolitics); } } //学生查看成绩 void Student_Watch_Grade(Student* student) { printf("查看学生%d %s的成绩\n",student->id,student->name); student->scores.Math!=(-1)?printf("Math : %d\n", student->scores.Math):printf("Math: 未录入\n"); student->scores.English!=(-1)?printf("English : %d\n", student->scores.English):printf("English: 未录入\n"); student->scores.Computer!=(-1)?printf("Computer: %d\n", student->scores.Computer):printf("Computer: 未录入\n"); student->scores.Politics!=(-1)?printf("Politics: %d\n", student->scores.Politics):printf("Politics: 未录入\n"); student->GPA!=(-1)?printf("GPA : %.2f\n", student->GPA):printf("GPA: 没有数据\n"); } long long quick_pow(long long base, long long power, long long mod) { long long result = 1; base = base%mod; while (power>0) { if (power%2==1) { result=(result * base) % mod; } power = power >> 1; base = (base * base) % mod; } return result; } // 加密函数 long long encrypt(long long original_password) { return quick_pow(original_password, E, N); } // 解密函数 long long decrypt(long long ciphertext) { return quick_pow(ciphertext, D, N); } void Read_Password(Student*students,int student_number,Teacher*teachers,int teacher_number,TreeNode* root) { //从文件中读取全部曾经手动创建过的密码,并存储 FILE* fStudent = fopen(STUDENT_PASSWORD_URL, "a"); fclose(fStudent); fStudent = fopen(STUDENT_PASSWORD_URL, "r"); if(fStudent!=NULL)//一定为非NULL,因为刚刚创建过文件 { //读取文件内容,并找到每一行的id的人的数组位置,解密后存进 int id; long long public_key; while(fscanf(fStudent,"%d %lld",&id,&public_key)==2) { TreeNode* target_stu = find(root,id); if(target_stu!=NULL)//找到这个人 { target_stu->student->password = decrypt(public_key);//解密后存进数组 } } //读取结束,关闭文件 fclose(fStudent); } //读取教师密码 FILE* fTeacher = fopen(TEACHER_PASSWORD_URL, "a"); fclose(fTeacher); fTeacher = fopen(TEACHER_PASSWORD_URL, "r"); if(fTeacher!=NULL) { int id; long long public_key; while(fscanf(fTeacher,"%d %lld",&id,&public_key)==2) { //由于教师数量有限,遍历查找即可 for(int i=0;istudent->money = money; } } fclose(fMoney); } } void Moneys_System(Student* student,int student_number,BusSchedule *b1,BusSchedule *b2,int bn1,int bn2) { printf("余额为:%.2lf",student->money); printf("以下为已有功能\n"); printf("1.预约\n"); printf("2.退出\n"); int choice; scanf("%d",&choice); switch(choice) { // case 1: // { // float money; // printf("请输入充值金额:"); // scanf("%lf",&money); // student->money+=money; // // FILE* fMoney = fopen(MONEY_URL,"a"); // fprintf(fMoney,"%d %.2lf\n",student->id,student->money); // fclose(fMoney); // printf("目前余额为%.2lf\n",student->money); // printf("充值成功\n"); // break; case 1: { printf("请输入预约选项:\n"); printf("1.班车预约\n2.退出\n"); int choice_buy; scanf("%d",&choice_buy); switch(choice_buy) { case 1: { int abc; printf("请选择你要预约哪辆班车:\n"); printf("1.南湖-浑南\n2.浑南-南湖\n3.退出\n"); scanf("%d",&abc); if(abc==1) { printf("以下为班车1的信息:\n"); Print_Bus_Conditions(BUS_ROUTE_ONE); } else if(abc==2) { printf("以下为班车2的信息:\n"); Print_Bus_Conditions(BUS_ROUTE_TWO); } else { printf("输入错误,自动退出\n"); break; } printf("请选择你的预约序号(班车时间前的序号):\n"); int choice_bus; scanf("%d",&choice_bus); printf("预约成功\n"); //扣费 student->money-=BUS_RESERVE_COST; //更新余额 FILE* fMoney = fopen(MONEY_URL,"a+"); fprintf(fMoney,"%d %.2lf\n",student->id,student->money); fclose(fMoney); printf("余额为:%.2lf",student->money); break; } // case 2: // { // printf("以下为场地预约信息:\n"); // //读取场地预约信息 // printf("预约成功\n"); // //扣费 // student->money-=FACILITY_RESERVE_COST; // //更新余额 // FILE* fMoney = fopen(MONEY_URL,"a+"); // fprintf(fMoney,"%d %.2f\n",student->id,student->money); // fclose(fMoney); // break; // } case 2: { printf("退出成功\n"); Sleep(1000); system("cls"); break; } default: { printf("输入错误,自动退出\n"); break; } } break; } case 2: { printf("退出成功\n"); Sleep(1000); system("cls"); } default: { printf("输入错误,自动退出\n"); break; } } } //班车管理 //设置班车日期及时间 void inputBusSchedule(BusSchedule *schedule) { printf("请输入班车日期:"); scanf("%s",schedule->date); printf("请输入班车时间:"); scanf("%s",schedule->time); } //将班车日期及时间存入文件并为其编号 void saveBusScheduleToFile(const BusSchedule *schedule,const char *filename,int counter) { FILE *file = fopen(filename,"a+"); fprintf(file,"%d. ",counter); fprintf(file,"%s ",schedule->date); fprintf(file,"%s",schedule->time); fprintf(file,"\n"); printf("班车设置成功\n"); fclose(file); } int Counter(const char *filename) { FILE *file=fopen(filename, "a+"); int maxCounter=0; int currentCounter; while(fscanf(file,"%d.",¤tCounter)==1) { if(currentCounter>maxCounter) { maxCounter=currentCounter; } // 跳过日期和时间,直到下一个序号 fscanf(file,"%*s %*s\n"); } fclose(file); return maxCounter; } BusSchedule* Print_Bus_Conditions(const char *filename) { FILE*fp = fopen(filename,"a+"); fclose(fp); fp = fopen(filename,"r"); int maxCount=0; char Date[30]; char Time[30]; int status; int Total_Counter = 0; Total_Counter=Counter(filename); BusSchedule* busSchedule = (BusSchedule*)malloc(sizeof(BusSchedule)*(Total_Counter+1)); while(fscanf(fp,"%d. %s %s",&maxCount,Date,Time)==3) { busSchedule[maxCount-1].index = maxCount; strcpy(busSchedule[maxCount-1].date,Date); strcpy(busSchedule[maxCount-1].time,Time); printf("%d.%s %s\n",maxCount,Date,Time); } return busSchedule; } int hashFunction(int id) { int hashValue = 3; const int prime = 31; hashValue = (hashValue ^ (id & 0xffff)) * prime; hashValue = (hashValue ^ ((id >> 2) & 0xffff)) * prime; hashValue = (hashValue ^ (id >> 1)) * prime; // const int prime = 31; // int hashValue = prime*id; return hashValue % TABLE_SIZE; } //创建哈希表并进行初始化 HashTable* createHashTable(void) { HashTable* table = (HashTable*)malloc(sizeof(HashTable)); if (table) { for(int i=0;istudents[i]=NULL; } } return table; } //插入 bool insertStudent(HashTable* table, Student* student) { if(!table || !student) return false; int index = hashFunction(student->id); if(!table->students[index]) //未产生哈希冲突/对应位置没有数据 { table->students[index] = student; student->next = NULL; } else { //产生哈希冲突,通过链表实现依次添加 // Student* newStudent = (Student*)malloc(sizeof(Student)); // copyStudent(newStudent,student); Student* current = table->students[index]; while(current->next!=NULL) { current = current->next; } current->next = student; student->next = NULL; } return true; } //查找 Student* findStudent(HashTable* table, int id) { if (!table) return NULL; int index = hashFunction(id); Student* current = table->students[index]; if(current==NULL) return NULL; while (current!= NULL) { if (current->id == id) { return current; } current = current->next; } return NULL; } // 删除 bool deleteStudent(HashTable* table, int id) { if (!table) return false; Student* theStudent = findStudent(table,id); if(theStudent==NULL) return false;//查无此人 //如果查到这个人 //如果在哈希表上 int index = hashFunction(id); if(table->students[index]==theStudent) { table->students[index] = theStudent->next; } else { //如果在链表上 Student* current = table->students[index]; while(current->next != theStudent) { current = current->next; } current->next = theStudent->next; } free(theStudent); return true; } //清空哈希表和链表 bool freeHashTable(HashTable* table) { if(!table) return false; //找到链表并清空 for(int i=0;istudents[i]; current = current->next; while(current!=NULL) { Student* temp = current; current = current->next; free(temp); } } free(table); return true; } //编辑场地预约日期及时间 void inputSiteSchedule(siteSchedule *schedule) { printf("请输入场地可预约日期:"); scanf("%s",schedule->date); printf("请输入场地可预约时间:"); scanf("%s",schedule->time); } //将场地可预约的时间和日期写入文件,并为其编号 void saveSiteScheduleToFile(const siteSchedule *schedule,const char *filename,int counter) { FILE *file = fopen(filename,"a+"); fprintf(file,"%d. ",counter); fprintf(file,"%s ",schedule->date); fprintf(file,"%s",schedule->time); fprintf(file,"\n"); printf("场地设置成功\n"); fclose(file); }