2387 lines
70 KiB
C++
2387 lines
70 KiB
C++
#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);
|
||
//打开/创建成绩文件,文件名格式为:教工号课程名班级号.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;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);
|
||
//打开/创建成绩文件,文件名格式为:教工号课程名班级号.txt,如:Math.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.",¤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;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);
|
||
}
|
||
|