Files
SchoolManager/主函数.cpp
ChuXun 6e631c8085 1
2025-10-19 13:29:40 +08:00

2387 lines
70 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#include<windows.h>
#include<ctype.h>
#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);
//打开/创建成绩文件,文件名格式为:教工号课程名班级号.txtMath.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;i<strlen(college_name);i++)
{
if(isdigit(college_name[i]))
{
has_digit=1;
break;
}
}
if (!has_digit)
{
fprintf(college_file,"%d %s\n",college_number*1000,college_name);
college_number++;
}
}
fclose(college_file);
college_number-=1;
(*number)=college_number;
}
//读取存储学院数量的文件,若已有数量则相加
void Write_File_College_Number(int number)
{
FILE* fp = fopen(COLLEGE_NUMBER_URL,"w+");
fprintf(fp,"%d",number);
fclose(fp);
}
void Read_File_College_Number(int *number)
{
FILE *fp = fopen(COLLEGE_NUMBER_URL, "r+");
if(fp)
{
int result = fscanf(fp, "%d", number);
if (result == 1)
{
return;
}
else
{
*number = 0;
}
fclose(fp);
}
else
{
*number = 0;
}
}
//读取文件"colleges.txt"中的学员信息并存储为结构体数组,(文件必须存在)
Colleges* Read_College(int college_number)
{
FILE *college_file=fopen(COLLEGE_URL,"r");
if(college_file==NULL)
{
perror("打开文件失败");
return NULL;
}
Colleges* colleges = (Colleges*)malloc(sizeof(Colleges) * (college_number));
if(colleges==NULL)
{
perror("动态分配失败");
fclose(college_file);
return NULL;
}
for(int i=0;i<college_number;i++)
{
if (fscanf(college_file, "%d %s", &colleges[i].id, colleges[i].college_name) != 2)
{
perror("读取文件失败");
free(colleges);
fclose(college_file);
return NULL;
}
}
fclose(college_file);
return colleges;
}
// 读取文件中的专业数量
void Read_File_Major_Number(int *major_number)
{
FILE *fp = fopen(MAJOR_NUMBER_URL, "r");
if (fp)
{
if(fscanf(fp, "%d",major_number)!=1)
{
*major_number=0;
}
}
else
{
*major_number = 0; // 如果文件不存在则初始化为0
}
fclose(fp);
}
// 管理员输入专业信息
//打开文件--循环输入学院id与专业名称--查找到相应的学院后--计算出专业id
// 以"%d %s %d\n",专业id,专业名学院id 的形式存进 MAJOR_URL
//开头需要printf("请输入学院id与专业名称按回车输入下一个按ctrl+Z停止输入\n");
void Admin_Major(Colleges* colleges, int college_number,int* major_number)
{
FILE *major_file = fopen(MAJOR_URL, "a+");
if(!major_file){
perror("文件打开失败");
return;
}
int major_counter=*major_number;
int college_id;
char major_name[23];
while(scanf("%d %s",&college_id,major_name)==2)
{
int valid_college=0;
for(int i=0;i<college_number;i++)
{
if(college_id==colleges[i].id)
{
valid_college=1;
++major_counter;
fprintf(major_file, "%d %s %d\n",college_id+(major_counter),
major_name,college_id);
break;
}
}
if(!valid_college){
printf("Invalid college ID. Please enter a valid college ID.\n");
}
}
fclose(major_file);
*major_number = major_counter;
}
void Write_File_Major_Number(int number)
{
FILE* fp = fopen(MAJOR_NUMBER_URL, "w");
if (!fp)
{
perror("Failed to open Major_number.txt for writing");
exit(EXIT_FAILURE);
}
fprintf(fp,"%d",number); //写入新的总数
fclose(fp);
}
// 栈-读取专业信息
//以"%d %s %d", &majors[i].id, majors[i].name, &majors[i].college_id 写进文件 MAJOR_URL
Major* Read_Major(int major_number)
{
FILE *file = fopen(MAJOR_URL,"r");
if(!file){
perror("打开失败");
return NULL;
}
Major* majors = (Major*)malloc(sizeof(Major)*major_number);
if (!majors){
perror("内存分配失败");
return NULL;
}
for (int i = 0; i <major_number;i++) {
fscanf(file, "%d %s %d", &majors[i].id, majors[i].name, &majors[i].college_id);
}
fclose(file);
return majors;
}
//打印学院信息
void Print_College(Colleges* colleges, int college_number)
{
printf("以下为学院列表\n");
for(int i=0;i<college_number;i++)
{
printf("%05d %s\n",colleges[i].id,colleges[i].college_name);
}
}
///归并排序
// 根据课程名查找对应的成绩
int getCourseScore(Student* student, const char* courseName)
{
if (strcmp(courseName, "Math") == 0)
{
return student->scores.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 (i<n1&&j<n2)
{
if(compareStudents(&leftArray[i],&rightArray[j],courseName)<=0)
{
array[k] = leftArray[i];
i++;
}
else
{
array[k]=rightArray[j];
j++;
}
k++;
}
// 复制剩余元素
while(i<n1)
{
array[k]=leftArray[i];
i++;
k++;
}
while(j<n2)
{
array[k]=rightArray[j];
j++;
k++;
}
// 释放临时数组
free(leftArray);
free(rightArray);
}
// 归并排序递归函数
void mergeSort(Student* array, int left, int right,const char* courseName) {
if (left<right)
{
int mid=left+(right-left)/2;
// 排序左右两个子数组
mergeSort(array, left, mid, courseName);
mergeSort(array, mid + 1, right, courseName);
// 合并排序好的子数组
merge(array, left, mid, right, courseName);
}
}
///二叉树添加并存储学生信息
// 插入节点到二叉树
TreeNode* insert(TreeNode* root, Student* student)
{
if (root == NULL)
{
TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));
newNode->student = 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<size;i++)
{
int score = getCourseScore(&students[i],courseName);
if(strcmp(courseName,"id")==0)
{
printf("ID: %08d, Name: %-12s,Class: %08d\n", students[i].id, students[i].name,score);
}
else if(strcmp(courseName,"Math")==0||strcmp(courseName,"English")==0||strcmp(courseName,"Computer")==0)
{
printf("ID: %08d, Name: %-12s, Class: %5d, %s Score: %3d\n", students[i].id, students[i].name, students[i].Class,courseName, score);
}
else if(strcmp(courseName,"Class")==0)
{
printf("ID: %08d, Name: %-12s, Class: %5d\n", students[i].id, students[i].name, students[i].Class);
}
}
}
//在给定学院中选择学院和专业 bool:true/false
bool select_college(Colleges* colleges,int college_number,char* college)
{
Print_College(colleges,college_number);
printf("请选择该成员所在的学院:(输入学院编号)\n");
int choice;
scanf("%d",&choice);
for(int i=0;i<college_number;i++)
{
if(colleges[i].id == choice)
{
strcpy(college,colleges[i].college_name);
return true;
}
}
return false;
}
bool select_major(Colleges* colleges,int college_number,
Major* majors,int major_number,
char* college,char* major)
{
//根据college的名字找到其所属专业
//先获取college的学院id再根据这个id找到一系列专业
int college_index = 0;
for(int j=0;j<college_number;j++)
{
if(strcmp(colleges[j].college_name,college)==0)
{
college_index = colleges[j].id;
}
}
printf("以下为该学院下的专业列表\n");
for(int i=0;i<major_number;i++)//确定了一个专业
{
if(majors[i].college_id == college_index)
{
printf("%05d %s : %05d %s\n",colleges[i].id,colleges[i].college_name,
majors[i].id,majors[i].name);
}
}
printf("请选择该学生所选的专业:(输入专业编号)\n");
int choice;
scanf("%d",&choice);
for(int i=0;i<major_number;i++)
{
if(majors[i].id == choice)
{
//找到这个专业以后把名字赋值给major
strcpy(major,majors[i].name);
return true;
}
}
return false;
}
//读取先前的学生数量
void Read_File_Student_Number(int* student_number)
{
FILE *fp = fopen(STUDENT_NUMBER_URL, "r");
if(fp)
{
if(fscanf(fp,"%d",student_number)!=1)
{
*student_number = 0;
}
fclose(fp);
}
else
{
*student_number = 0;
}
}
//初始化学生,并存进文件
void inputStudentInfo(Colleges* colleges,int college_number,Major* majors,int major_number,
int* student_number)
{
int n;
printf("请输入需要添加进系统的学生数量: ");
scanf("%d", &n);
Student* students = (Student*)malloc(sizeof(Student) * n);
*student_number += n;
for (int i=0; i<n; i++)
{
printf("\n请输入学生 %d 的信息:\n",i+1);
//学号
printf("ID: ");
scanf("%d", &students[i].id);
//姓名
printf("姓名: ");
scanf("%s", students[i].name);
//性别选择
printf("性别(男或女):");
char gender[3];
while(true)
{
scanf("%s", gender);
if(strcmp(gender,"")==0 || strcmp(gender,"")==0)
{
strcpy(students[i].gender,gender);
break;
}
else
{
printf("输入错误,请重新输入:");
}
}
//学院选择
select_college(colleges,college_number,students[i].college);
//专业选择
select_major(colleges,college_number,majors,major_number,
students[i].college,students[i].major);
//班级添加:四位有效数字
printf("班级ID:(四位有效数字)");
int class_id;
while(true)
{
scanf("%d", &class_id);
if(class_id>=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;i<student_number;i++)
{
fscanf(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);
return students;
}
//给学生未赋值的数值初始化,如余额
void Undefined_Inital_Stu(Student* students,int student_number)
{
for(int i=0;i<student_number;i++)
{
students[i].money=0;
students[i].dorm_index=-1;
students[i].scores.Computer=-1;
students[i].scores.English=-1;
students[i].scores.Math=-1;
students[i].scores.Politics=-1;
students[i].GPA = -1;
}
}
//读取先前的教师数量
void Read_File_Teacher_Number(int* teacher_number)
{
FILE *fp = fopen(TEACHER_DATA_URL, "r");
if(fp)
{
if(fscanf(fp,"%d",teacher_number)!=1)
{
*teacher_number = 0;
}
}
else
{
*teacher_number = 0;
}
fclose(fp);
}
//初始化教师,并存进文件
void inputTeacherInfo(Colleges* colleges,Course courses[],int college_number,int* teacher_number)
{
int n;
printf("请输入需要添加进入系统的教师数量: ");
scanf("%d", &n);
*teacher_number += n;
Teacher* teachers=NULL;
if(n>0)
teachers = (Teacher*)malloc(sizeof(Teacher) * n);
for (int i=0;i<n;i++)
{
printf("\n请输入教师 %d 的信息:\n",i+1);
//教工号
printf("ID: ");
scanf("%d", &teachers[i].id);
//姓名
printf("姓名: ");
scanf("%s", teachers[i].name);
//性别选择
printf("性别(男或女):");
char gender[3];
while(true)
{
scanf("%s", gender);
if(strcmp(gender,"")==0 || strcmp(gender,"")==0)
{
strcpy(teachers[i].gender,gender);
break;
}
else
{
printf("输入错误,请重新输入:");
}
}
//学院选择
select_college(colleges,college_number,teachers[i].college);
//课程选择
printf("以下为已有课程: \n");
for(int j=0;j<4;j++)
{
printf("%s\n",courses[j].name);
}
while(true)
{
printf("请选择该教师教授课程(输入名称):");
char course_name[20];
scanf("%s", course_name);
bool result = false;
for(int j=0;j<4;j++)
{
if(strcmp(course_name,courses[j].name)==0)
{
strcpy(teachers[i].course,courses[j].name);
result = true;
break;
}
}
if(result) break;
}
//授课班级选择
while(true)
{
printf("请输入授课班级4位数字");
scanf("%d",&teachers[i].teaching_class);
if(teachers[i].teaching_class>=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;i<teacher_number;i++)
{
fscanf(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);
return teachers;
}
return NULL;
}
//教师登录
bool Teacher_Login(Teacher* teachers,Teacher *target_teacher,int teacher_number)
{
int count = 0;
printf("你只有三次机会请谨慎输入密码初始密码为工号由于测试原因直接给出00010001\n");
while(true)
{
if(count==3)
{
printf("输入错误次数过多,请稍后再试!\n");
return false;
}
int id;
printf("请输入教工号:");
scanf("%d",&id);
long long password;
printf("请输入密码(初始密码为工号):");
scanf("%lld",&password);
for(int i=0;i<teacher_number;i++)
{
if(teachers[i].id == id && teachers[i].password == password)
{
printf("登录成功!\n");
*target_teacher = teachers[i];
return true;
}
}
++count;
printf("教工号或密码错误,请重新输入!\n");
}
}
//教师录入学生成绩,并存进文件
void Teacher_Import_Grade(Student*students,int student_number,
Teacher *teacher,int teacher_number,
Course* courses)
{
char temp_course_url[30];
sprintf(temp_course_url,"%s.txt",teacher->course);
//打开/创建成绩文件,文件名格式为:教工号课程名班级号.txtMath.txt
//数据存储格式学号加空格加成绩20245738 90
FILE* fp = fopen(temp_course_url,"a+");
for(int i=0;i<student_number;i++)
{
if(students[i].Class == teacher->teaching_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;i<student_number;i++)
{
students[i].password = students[i].id;
}
for(int i=0;i<teacher_number;i++)
{
teachers[i].password = teachers[i].id;
}
}
//更新某个学生的GPA
void Update_GPA(Student* student,Course courses[], int student_number)
{
double temp_GPA = Total_GPA_Calculation(student,courses,student_number);
student->GPA = 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;i<student_number;i++)
{
if(students[i].id == id && students[i].password == password)
{
printf("登录成功!\n");
*target_student = students[i];
return true;
}
}
++count;
printf("学号或密码错误,请重新输入!\n");
}
}
//自动更新学生的成绩
void Students_Read_Grade_File(TreeNode* root,int student_number)
{
// 读取学生成绩文件,并存储到相应的结构体中
int temp_id;
int temp_score;
FILE* fMath = fopen("Math.txt", "r");
int status;
if(fMath!=NULL)
{
while((status = fscanf(fMath, "%d %d", &temp_id, &temp_score))!=EOF && status==2)
{
TreeNode* result = find(root, temp_id);
if (result!=NULL)
{
result->student->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;i<teacher_number;i++)
{
if(teachers[i].id==id)//找到这个人,意味着他曾经手动设置过密码,则存储进数组
{
teachers[i].password = decrypt(public_key);
}
}
}
fclose(fTeacher);
}
}
void Read_Money(Student*students,int student_number,Teacher*teachers,int teacher_number,TreeNode* root)
{
FILE* fMoney = fopen(MONEY_URL,"a");
fclose(fMoney);
fMoney = fopen(MONEY_URL,"r");
if(fMoney!=NULL)
{
int id;
double money;
while(fscanf(fMoney,"%d %lf",&id,&money)==2)
{
TreeNode* target = find(root,id);
if(target!=NULL)
{
target->student->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.",&currentCounter)==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;i<TABLE_SIZE;i++)
{
table->students[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;i<TABLE_SIZE;i++)
{
Student* current = table->students[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);
}