.h
#pragma once
#define MAXN 30
#define STU_F "D:\\Codes C\\vs\\学生选课系统\\student.txt"
#define COUR_F "D:\\Codes C\\vs\\学生选课系统\\course.txt" //文件存放路径及文件名
#define MAN_F "D:\\Codes C\\vs\\学生选课系统\\manager.txt"struct Student //学生信息结构体
{char name[MAXN]; //姓名char num[MAXN]; //学号char sch_cla[MAXN]; //学院和班级double score_all; //已选课总学分char password[7]; //学生登陆密码,共6位int course_sum; //选课总数char course[50][MAXN]; //记录选课课程的编号struct Student* next;
};
typedef struct Student student;struct Course //课程信息结构体
{char num[MAXN]; //课程编号char name[MAXN]; //课程名称char nature[MAXN]; //课程性质double time_all; //总学时double time_teach; //授课学时double time_exp; //实验或上机学时double score; //该课程学分char term[5]; //开课学期int stu_sum; //已经选课学生总数struct Course* next; //链表指针
};
typedef struct Course course;extern student* stu_head;
extern student* stu_tail;
extern course* cour_head;
extern course* cour_tail;/*COMMEN*/int judge_num(char* ch); //用于检测输入的字符串ch是否全部为数字,全部为数字则返回1,否则返回0
int input_num(); //用于输入数字,如果输入的全部为数字则返回该数字,否则一直停在输入状态
double input_double(); //用于输入小数
int input_limit(int n); //输入选项,控制输入的数字范围为0-n,在这个范围内则返回该数字,否则一直停在输入状态
int input_limit0(int n);
int input_limitn(int n, int x);
student* load_stu(); //将学生文件生成链表,返回链表头指针
void store_stu(student* p_head); //将学生链表存入学生文件,需传入链表头指针
course* load_cour(); //将课程文件生成链表,返回链表头指针
void store_cour(course* p_head); //将课程链表存入课程文件,需传入链表头指针 student* locate_end(student* head); //传入头节点,返回尾节点
course* locate1_end(course* head); //传入头节点,返回尾节点//int link_count1(course* head); //计算链表节点数量
//int link_count(student* head);
int judge_ascii_num(char in[]); //检测输入是否全部为ASCII的数字,是返回1否则返回0
void stu_file_intialize(); // 初始化学生信息
void cour_file_intialize(); // 初始化课程信息/*管理员*/int man_login(); //管理员登陆函数,密码正确返回1,否则返回0
int man_menu(); //管理员主菜单,返回对应的输入值
void student_add(student* head); //增加学生的函数
void student_delete(student* head); //删除学生的函数
void man_search_stu(student* head); //搜索学生的函数
void student_modify(student* head); //管理员修改学生信息
void course_add(course* head); //增加课程的函数
void course_delete(course* head); //删除课程的函数
void course_modify(course* head); //修改课程信息的函数
void courseshowone_man(course* ad); //管理员显示一门课程信息
void courseshowall_man(course* ad); //管理员显示所有课程信息
void count_peo(student* head); //统计选修课人数
//void print_all();//打印所有信息/*学生*/student* stu_login(student* head); //学生登陆函数,学号和密码都正确则返回链表中该学生的指针,错误则返回null
int stu_menu(); //学生菜单,返回对应的输入值
void student_showone(student* p); //显示一个学生的信息
void student_showall(student* head); //显示所有学生的信息
student* studentnamefind_char(student* head, char tar[]); //根据学生姓名查找学生,如果学生为头节点则返回空指针,不为头节点则返回前一个节点的指针,不存在则返回尾节点
student* studentnamefind_num(student* head, char tar[]); //根据学生学号查找学生,如果学生为头节点则返回空指针,不为头节点则返回前一个节点的指针,不存在则返回尾节点
void coursechoose(course* head, student* stu); //选课函数,min为最少要达到的学分
void courseshow_nature(course* head); //根据课程性质查找并显示课程信息
void courseshow_score(course* head); //根据学分查找并显示课程信息
void show_schedule(student* stu); //显示课表
void stu_dele_cour(course* head, student* stu);//学分大于60就删除/*COURSE*/
void course_showone(course* ad); //显示一门的信息
void course_showall(course* head); //显示所有课程的信息
void search_course(course* head); //搜索课程的函数
course* coursenamefind_char(course* head, char tar[]); //根据课程名称查找课程节点,如果课程为头节点则返回空指针,不为头节点则返回前一个节点的指针,不存在则返回尾节点
course* coursenumfind_num(course* head, char tar[]); //
.commen
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<malloc.h>
#include<ctype.h>
#include"student.h"int input_limit0(int n)
{int m;while (1){m = input_num();if (m >= 0 && m <= n)break;printf("\n\t\t####无此选项,请重新输入!####\n");}return m;
}int input_limit(int n)//输入的数字必须在(0,n]之间
{int m;while (1){m = input_num();if (m > 0 && m <= n)break;printf("\n\t\t####无此选项,请重新输入!####\n");}return m;
}int input_limitn(int n, int x)
{int m;while (1){m = input_num();if (m >= n && m <= x)break;printf("\n\t\t####无此选项,请重新输入!####\n");}return m;
}int input_num() //知道输入的字符串全部为数字为止
{int num;char buf[MAXN];while ((scanf("%s", buf) == 0) || (judge_num(buf) == 0)){while (getchar() != '\n');printf("\n\t\t###输入错误,请重新输入:");}num = atoi(buf);return num;
}int judge_num(char* ch) //字符串是否全是数字
{int sum = 0, len = strlen(ch);for (int i = 0; i < len; i++){if (ch[i] >= '0' && ch[i] <= '9')sum++;}if (sum == len)return 1;elsereturn 0;
}int judge_ascii_num(char in[])
{int i = 0;while (in[i] != '\0'){if ((in[i] < '0') || (in[i] > '9'))return 0;i++;}return 1;}double input_double()
{double temp = -1.00;while (1){scanf("%lf", &temp);while (getchar() != '\n');if (temp < 0)printf("\n\t\t#####输入错误,请重新输入:");elsebreak;}return temp;
}/*void stu_file_intialize() // 初始化学生信息
{FILE* fp;student* p=(student*)malloc(sizeof(student));if ((fp = fopen(STU_F, "w")) == NULL){printf("\t***STU_F missed,please quit the system and check for that!\n\n");exit(0);}printf("\n\t\t输入学生姓名(输入“000”结束)");scanf("%s", p->name);while(strcmp(p->name, "000") != 0){printf("\n\t\t输入学号:");scanf("%s", p->num);printf("\n\t\t输入学院班级:");scanf("%s", p->sch_cla);printf("\n\t\t输入总学分:");scanf("%lf",& p->score_all);printf("\n\t\t输入密码(六位):");scanf("%s", p->password);printf("\n\t\t输入选课总数:");scanf("%d", &p->course_sum);strcmp(p->course[0], "0000");fwrite(p, sizeof(student), 1, fp);printf("\n\t\t输入学生姓名(输入“000”结束):");scanf("%s", p->name);}fclose(fp);
}void cour_file_intialize() // 初始化课程信息
{FILE* fp;course* p= (course*)malloc(sizeof(course));;if ((fp = fopen(COUR_F, "w")) == NULL){printf("\t***COUR_F missed,please quit the system and check for that!\n\n");exit(0);}printf("\n\t\t输入课程编号(输入“0000”结束)");scanf("%s", p->num);while (strcmp(p->num, "0000") != 0){printf("\n\t\t输入课程名称:");scanf("%s", p->name);printf("\n\t\t输入课程性质:");scanf("%s", p->nature);printf("\n\t\t输入总学时:");scanf("%lf", &p->time_all);printf("\n\t\t输入授课学时:");scanf("%lf",& p->time_teach);printf("\n\t\t输入实验或上机学时:");scanf("%lf", &p->time_exp);printf("\n\t\t输入学分:");scanf("%lf", &p->score);printf("\n\t\t输入开课学期:");scanf("%s", &p->term);printf("\n\t\t输入已选人数:");scanf("%d", &p->stu_sum);fwrite(p, sizeof(course), 1, fp);printf("\n\t\t输入课程编号(输入“0000”结束):");scanf("%s", p->num);}fclose(fp);
}*/void store_stu(student* p_head)//经调试已正确
{FILE* fp;if ((fp = fopen(STU_F, "w")) == NULL)//以只写方式打开文件,覆盖以前数据{printf("\t***STU_F missed,please quit the system and check for that!\n\n");exit(0);}while (p_head != NULL)//将链表所有节点写入缓冲区{fwrite(p_head, sizeof(student), 1, fp);//将链表一个节点写入缓冲区p_head = p_head->next; //p_head指向下一个节点}fclose(fp);//保存文件,清空缓冲区
}student* load_stu()//经调试已经正确
{int count = 0;FILE* fp;if ((fp = fopen(STU_F, "r")) == NULL){printf("\t\tcannot open the file:STU_F\n");exit(0);}student* temp = (student*)malloc(sizeof(student));while (!feof(fp)){if (fread(temp, sizeof(student), 1, fp))count++;}free(temp);temp = NULL;if (count == 0)return NULL;else{rewind(fp);student* p_head = NULL;//文件中有链表信息,则创建一个头指针p_head = (student*)malloc(sizeof(student));fread(p_head, sizeof(student), 1, fp);//用文件内容初始化链表节点p_head->next = NULL;count--;student* p_new = p_head;student* p_end = p_head;for (int i = 0; i < count; i++){p_new = (student*)malloc(sizeof(student));fread(p_new, sizeof(student), 1, fp);p_new->next = NULL;p_end->next = p_new;p_end = p_new;}fclose(fp);return p_head;}
}course* load_cour()
{int count = 0;FILE* fp;if ((fp = fopen(COUR_F, "r")) == NULL){printf("\t\tcannot open the file:COUR_F\n");exit(0);}course* temp = (course*)malloc(sizeof(course));while (!feof(fp)){if (fread(temp, sizeof(course), 1, fp))count++;}free(temp);temp = NULL;if (count == 0)return NULL;else{rewind(fp);course* p_head = NULL;//文件中有链表信息,则创建一个头指针p_head = (course*)malloc(sizeof(course));fread(p_head, sizeof(course), 1, fp);//用文件内容初始化链表节点p_head->next = NULL;count--;course* p_new = p_head;course* p_end = p_head;for (int i = 0; i < count; i++){p_new = (course*)malloc(sizeof(course));fread(p_new, sizeof(course), 1, fp);p_new->next = NULL;p_end->next = p_new;p_end = p_new;}fclose(fp);return p_head;}}void store_cour(course* p_head)
{FILE* fp;if ((fp = fopen(COUR_F, "w")) == NULL)//以只写方式打开文件,覆盖以前数据{printf("\t***COUR_F missed,please quit the system and check for that!\n\n");exit(0);}while (p_head != NULL)//将链表所有节点写入缓冲区{fwrite(p_head, sizeof(course), 1, fp);//将链表一个节点写入缓冲区p_head = p_head->next; //p_head指向下一个节点}fclose(fp);//保存文件,清空缓冲区
}/*int link_count(student* head)
{int count = 0;while (head != NULL){count++;head = head->next;}return count;
}int link_count1(course* head)
{int count = 0;while (head != NULL){count++;head = head->next;}return count;
}
*/student* locate_end(student* head)
{student* end = head;while (head != NULL){end = head;head = head->next;}return end;
}course* locate1_end(course* head)
{course* end = head;while (head != NULL){end = head;head = head->next;}return end;
}
.course
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<malloc.h>
#include<ctype.h>
#include"student.h"void search_course(course* head)
{int flag;while (1){flag = 0;printf("\n\t\t请输入查找条件 [1]课程学分 [2]课程性质 [3]返回上级菜单:");scanf("%d", &flag);while (getchar() != '\n');switch (flag){case 1:courseshow_score(head); break;case 2:courseshow_nature(head); break;case 3:break;default:printf("\n\t\t#####输入错误,请重新输入!#####");}if (flag == 0||flag==3)break;}
}course* coursenamefind_char(course* head, char tar[])//根据课程名称查找课程节点,返回前一节点地址
{course* p, * q;p = head;q = NULL;while (p != NULL){if (strcmp(tar, p->name) == 0)return q;q = p;p = p->next;}return q;
}course* coursenumfind_num(course* head, char tar[])//根据课程编号查找课程
{course* p, * q;p = head;q = NULL;while (p != NULL){if (strcmp(tar, p->num) == 0)return q;q = p;p = p->next;}return q;}void course_showone(course* ad)
{if (ad == NULL)printf("\t\t无课程\n");else{printf("\n\t\t------------------------------------------------------");printf("\n\t\t课程名称:%s\n", ad->name);printf("\n\t\t课程编号:%s\n", ad->num);printf("\t\t课程性质:%s\n", ad->nature);printf("\t\t开课学期:%s\n", ad->term);printf("\t\t总学时: %lf\n", ad->time_all);printf("\t\t授课学时:%lf\n", ad->time_teach);printf("\t\t实验或上机学时:%lf\n", ad->time_exp);printf("\t\t学分:%lf\n\n", ad->score);printf("\t\t已选人数:%d\n\n", ad->stu_sum);printf("\n\t\t------------------------------------------------------");}
}void course_showall(course* head)
{course* p;p = head;while (p != NULL){course_showone(p);p = p->next;}return;
}
.main
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"student.h"student* stu_head;
student* stu_tail;
course* cour_head;
course* cour_tail;
student* p_stu;int main()
{//stu_file_intialize(); // 初始化学生信息//cour_file_intialize(); // 初始化课程信息stu_head = load_stu(); //stu_head指向学生链表头stu_tail = locate_end(stu_head); //stu_tail指向学生链表尾cour_head = load_cour(); //cour_head指向课程链表头cour_tail = locate1_end(cour_head); //cour_tail指向课程链表尾int status = -1;int menu_return;student* p_stu;char input[100];while (1){status = -1;printf("\t\t~~~~~~~~~~欢迎进入选课系统~~~~~~~~~~\n");printf("\t\t[1]学生登陆\n");printf("\t\t[2]管理员登陆\n");printf("\t\t[3]退出系统\n");status = input_limit(3);//判断输入是否合法if (status == 1 || status == 2 || status == 3)break;elseprintf("##### 输入错误!只能选择1,2,或者3 #####");}while (1){if (status == 2) //管理员登录{if (man_login() == 1){printf("\n\n\t\t~~~~~~~~~~管理员登陆成功~~~~~~~~~~~\n\n");menu_return = man_menu();while (1){switch (menu_return){//case 0:print_all(); break;case 3:count_peo(cour_head); break;case 4:break;case 5:student_add(stu_head); break;case 6:student_modify(stu_head); break;case 7:student_delete(stu_head); break;case 8:man_search_stu(stu_head); break;case 9:course_add(cour_head); break;case 10:course_modify(cour_head); break;case 11:course_delete(cour_head); break;case 12:search_course(cour_head); break;default:printf("\t\t\t#####输入错误,请重新输入######!\n");}if (menu_return == 4)break;menu_return = man_menu();}}elseprintf("\n\t\t~~~~~~~~~~~密码错误,请重新登录~~~~~~~~~~~");}else if (status == 1){p_stu = stu_login(stu_head);//p_stu指向登陆学生指针if (p_stu != NULL){printf("\t\t输入密码:");scanf("%s", input);while (getchar() != '\n');if (strcmp(p_stu->password, input) == 0){printf("\n\n\t\t~~~~~~~~~~学生登陆成功~~~~~~~~~~~\n\n");menu_return = stu_menu();while (1){switch (menu_return){case 1:search_course(cour_head); break;case 2:coursechoose(cour_head, p_stu); break;case 3:show_schedule(p_stu); break;case 4:; break;default:printf("\t\t\t#####输入错误,请重新输入######!\n");}if (menu_return == 4)break;menu_return = stu_menu();}}elseprintf("\n\t\t~~~~~~~~~~~密码错误,重新登陆!~~~~~~~~~~");}elseprintf("\n\t\t~~~~~~~~~~~学号不存在,重新登陆!~~~~~~~~~~");p_stu = NULL;}else if(status==3)return 0;while (1){status = -1;printf("\n\t\t~~~~~~~~~~欢迎进入选课系统~~~~~~~~~~\n");printf("\t\t[1]学生登陆\n");printf("\t\t[2]管理员登陆\n");printf("\t\t[3]退出系统\n");status = input_limit(3);//判断输入是否合法if (status == 1 || status == 2 || status == 3)break;elseprintf("\n\t\t##### 输入错误!只能选择1,2,或者3 #####");}}
}
.manager
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<malloc.h>
#include<ctype.h>
#include"student.h"extern student* stu_head;
extern course* cour_head;
extern course* cour_tail;
extern student* stu_tail;int man_login()
{FILE* fp;if ((fp = fopen(MAN_F, "r")) == NULL){printf("\t\t#######无法找到文件:MAN_F######\n");return -1;}char key[11];fgets(key, 9, fp);fclose(fp);char input[100];printf("\t\t*******请输入管理员密码:");scanf("%s", input);while (getchar() != '\n');if (strcmp(input, key) == 0)return 1;elsereturn 0;
}int man_menu()
{int n;printf("\n\t\t~~~~~~~~~~~管理员菜单~~~~~~~~~~");printf("\n\t\t[1]:管理学生信息");printf("\n\t\t[2]:管理课程信息\n");printf("\n\t\t[3]:统计每门课程的选修人数");printf("\n\t\t[4]退出\n");n = input_limit(4);if (n == 1){printf("\n\t\t[5]:录入学生信息");printf("\n\t\t[6]:修改学生信息");printf("\n\t\t[7]:删除学生信息\n");printf("\n\t\t[8]:查询学生信息\n");n = input_limitn(5, 8);}if (n == 2){printf("\n\t\t[9]:录入课程信息");printf("\n\t\t[10]:修改课程信息");printf("\n\t\t[11]:删除课程信息");printf("\n\t\t[12]:查询课程信息\n");n = input_limitn(8, 12);}return n;
}void student_add(student* head) //增加学生的函数
{while (1){char input[50];student_showall(head);while (1){printf("\n\t\t请输入要添加学生的学号(数字),返回上级菜单请输入0000:");scanf("%s", input);while (getchar() != '\n');if (judge_ascii_num(input) == 1)break;elseprintf("\n\t\t####输入错误!#####");}if (strcmp(input, "0000") == 0)break;if (studentnamefind_num(stu_head, input) != stu_tail){printf("\t\t###已存在该学生,请重新输入!####\n");continue;}/*初始化学生信息*/student* p = (student*)malloc(sizeof(student));strcpy(p->num, input);printf("\t\t请输入学生姓名:");scanf("%s", p->name);while (getchar() != '\n');printf("\t\t请输入学生学院和班级(例如光电学院2016级163):");scanf("%s", p->sch_cla);while (getchar() != '\n');printf("\t\t请输入当前该学生总学分:");p->score_all = input_double();p->course_sum = 0;strcpy(p->password, p->num);if (stu_head == NULL)//当前链表中没有节点{p->next = NULL;stu_head = p;stu_tail = p;}else{if (strcmp(p->num, stu_head->num) < 0)//新增节点的标号比头节点还小{p->next = stu_head;stu_head = p;}else if (strcmp(p->num, stu_tail->num) > 0)//新增节点的标号比尾节点还大{p->next = NULL;stu_tail->next = p;stu_tail = p;}else//新增节点的标号在头节点和尾节点之间{student* temp = stu_head;while (temp != stu_tail){if (strcmp(p->num, temp->num) > 0){p->next = temp->next;temp->next = p;break;}}}}printf("\n\t\t学生信息录入成功!\n");}store_stu(stu_head);
}void student_delete(student* head)
{while (1){student_showall(head);printf("\n\t\t请输入要删除学生的学号,取消删除请输入0000:");char input[50];scanf("%s", input);while (getchar() != '\n');if (strcmp(input, "0000") == 0)break;student* p;p = studentnamefind_num(stu_head, input);if (p == stu_tail)//没有该学生{printf("\n\t\t####没有该学生信息!#####");continue;}printf("\n\t\t确定删除%s?[1]是 [0]否:", input);int in = 0;scanf("%d", &in);while (getchar() != '\n');if (in == 1){if (p == NULL)//链表头节点{if (stu_head->next == NULL){stu_tail = NULL;}student* temp = stu_head;stu_head = stu_head->next;free(temp);temp = NULL;}else if (p->next == stu_tail)//链表尾节点{p->next = NULL;free(stu_tail);stu_tail = p;}else//链表中间节点{student* delete_point = p->next;p->next = delete_point->next;free(delete_point);delete_point = NULL;}printf("\n\t\t已经删除该学生的信息!\n");}elseprintf("\n\t\t####未删除该学生的信息!####\n");}store_stu(stu_head);
}void student_modify(student* head)
{char input[100];student* find = NULL;while (1){student_showall(head);while (1){printf("\n\t\t请输入要修改学生的学号,取消修改请输入0000:");scanf("%s", input);while (getchar() != '\n');if (judge_ascii_num(input) == 1)break;elseprintf("\n\t\t####输入错误!#####");}if (strcmp(input, "0000") == 0)break;find = studentnamefind_num(head, input);if (find == stu_tail){printf("\n\t\t####你所查找的学生不存在!");continue;}else{char temp[50];if (find == NULL)find = head;elsefind = find->next;printf("\n\t\t请分别输入需要修改的内容,若某一项不需要修改请输入0");printf("\n\t\t原姓名:%s 修改后的姓名:", find->name);scanf("%s", &temp);while (getchar() != '\n');if (strcmp(temp, "0") != 0)strcpy(find->name, temp);printf("\t\t原学院和班级:%s 修改后的学院和班级(例如光电学院2016级163):", find->sch_cla);scanf("%s", &temp);while (getchar() != '\n');if (strcmp(temp, "0") != 0)strcpy(find->sch_cla, temp);printf("\t\t原密码:%s 修改后的密码:", find->password);scanf("%s", &temp);while (getchar() != '\n');if (strcmp(temp, "0") != 0)strcpy(find->password, temp);printf("\t\t原总学分:%lf (增加学分请使用+,减少学分请使用-,例如“-10” “+10”):", find->score_all);scanf("%s", &temp);while (getchar() != '\n');if (strcmp(temp, "0") != 0){int change = (int)temp[0];temp[0] = '0';double number = atof(temp);if (change == 43)find->score_all += number;else if (change == 45)find->score_all -= number;}printf("\t\t修改完成!\n\n");}}store_stu(stu_head);
}void count_peo(course* head)
{course* p;char search[MAXN];while (1){int flag = 0, sum = 0;p = head;printf("\n\t\t请输入要查找人数的课程名称,取消查找请输入0000:");scanf("%s", search);while (getchar() != '\n');if (strcmp(search, "0000") == 0)break;while (p != NULL){if (strcmp(search, p->name) == 0){flag = 1;printf("\n\t\t选择%s的人数为%d", search, p->stu_sum);}p = p->next;}if (flag == 0)printf("\n\t\t没有该课程!####");}return;
}void course_add(course* head)
{while (1){char input[50];courseshowall_man(head);while (1){printf("\n\t\t请输入要添加课程的编号,返回上一级菜单请输入0000:");scanf("%s", input);while (getchar() != '\n');if (judge_ascii_num(input) == 1)break;elseprintf("\n\t\t#####输入错误!####");}if (strcmp(input, "0000") == 0)break;if (coursenumfind_num(cour_head, input) != cour_tail){printf("\t\t###已存在该课程,请重新输入!####\n");continue;}course* p = (course*)malloc(sizeof(course));/*初始化课程信息*/strcpy(p->num, input);printf("\n\t\t请输入课程名称:");scanf("%s", p->name);while (getchar() != '\n');printf("\n\t\t请输入课程性质:");scanf("%s", p->nature);while (getchar() != '\n');printf("\n\t\t请输入课程总学时:");p->time_all = input_double();printf("\n\t\t请输入课程授课学时:");p->time_teach = input_double();printf("\n\t\t请输入课程实验或上机学时:");p->time_exp = input_double();printf("\n\t\t请输入课程学分:");p->score = input_double();printf("\n\t\t请输入课程开课学期:");scanf("%s", p->term);while (getchar() != '\n');p->stu_sum = 0;if (cour_head == NULL)//链表中没有节点{p->next = NULL;cour_head = p;cour_tail = p;}else{if (strcmp(p->num, cour_head->num) < 0)//新增节点的标号比头节点还小{p->next = cour_head;cour_head = p;}else if (strcmp(p->num, cour_tail->num) > 0)//新增节点的标号比尾节点还大{p->next = NULL;cour_tail->next = p;cour_tail = p;}else//新增节点的标号在头节点和尾节点之间{course* temp = cour_head;while (temp != cour_tail){if (strcmp(p->num, temp->num) > 0){p->next = temp->next;temp->next = p;break;}}}}printf("\n\t\t课程信息录入成功!\n");}store_cour(cour_head);
}void course_delete(course* head)
{course* p;char input[50];int in = 0;course* temp;course* delete_point;while (1){courseshowall_man(head);printf("\n\t\t请输入要删除课程的编号或名称,取消删除请输入0000:");scanf("%s", input);while (getchar() != '\n');if (strcmp(input, "0000") == 0)break;if ((input[0] >= 48) && (input[0] <= 57))p = coursenumfind_num(head, input);elsep = coursenamefind_char(head, input);if (p == cour_tail)//没有该课程{printf("\n\t\t####没有该课程信息!####"); continue;}printf("\n\t\t确定删除%s?[1]是 [0]否:", input);scanf("%d", &in);while (getchar() != '\n');if (in == 1){if (p == NULL)//链表头节点{if (head->next == NULL)cour_tail = NULL;temp = head;head = head->next;cour_head = head;free(temp);}else if (p->next == cour_tail)//链表尾节点{free(cour_tail);p->next = NULL;cour_tail = p;}else//链表中间节点{delete_point = p->next;p = delete_point->next;free(delete_point);}printf("\n\t\t%s已经删除!\n", input);}elseprintf("\n\t\t#####未删除课程%s的信息!######\n", input);}store_cour(cour_head);
}void course_modify(course* head)
{char input[100];course* find = NULL;char temp[50];courseshowall_man(head);while (1){printf("\n\t\t请输入要修改课程的编号号或名称,取消修改请输入0000:");scanf("%s", input);while (getchar() != '\n');if (strcmp(input, "0000") == 0)break;if ((input[0] >= 48) && (input[0] <= 57))//按学号查找find = coursenumfind_num(head, input);else//按姓名查找find = coursenamefind_char(head, input);if (find == cour_tail){printf("\n\t\t####你所查找的课程不存在!####");continue;}else{if (find == NULL)find = head;elsefind = find->next;printf("\n\t\t请分别输入需要修改的内容,若某一项不需要修改请输入0");printf("\n\t\t原名称:%s 修改后的名称:", find->name);scanf("%s", &temp);while (getchar() != '\n');if (strcmp(temp, "0") != 0)strcpy(find->name, temp);printf("\t\t原性质:%s 修改后的性质:", find->nature);scanf("%s", &temp);while (getchar() != '\n');if (strcmp(temp, "0") != 0)strcpy(find->nature, temp);printf("\t\t原开课学期:%s 修改后的开课学期:", find->term);scanf("%s", &temp);while (getchar() != '\n');if (strcmp(temp, "0") != 0)strcpy(find->term, temp);//int time_all; //总学时//int time_teach; //授课学时//int time_exp; //实验或上机学时//int score; //该课程学分//int stu_max; //能够容纳的学生总数printf("\t\t原总学时:%lf 修改后的总学时:", find->time_all);scanf("%s", &temp);while (getchar() != '\n');if (strcmp(temp, "0") != 0)find->time_all = atof(temp);printf("\t\t原授课学时:%lf 修改后的授课学时:", find->time_teach);scanf("%s", &temp);while (getchar() != '\n');if (strcmp(temp, "0") != 0)find->time_teach = atof(temp);printf("\t\t原实验或上机学时:%lf 修改后的实验或上机学时:", find->time_exp);scanf("%s", &temp);while (getchar() != '\n');if (strcmp(temp, "0") != 0)find->time_exp = atof(temp);printf("\t\t原课程学分:%lf 修改后的课程学分:", find->score);scanf("%s", &temp);while (getchar() != '\n');if (strcmp(temp, "0") != 0)find->score = atof(temp);printf("\t\t修改完成!\n\n");}}store_cour(cour_head);
}/*void print_all()
{while (1){printf("\n\t\t选择操作类型: [1]打印所有学生信息 [2]打印所有课程信息 [0]返回主菜单:");int input = 0;scanf("%d", &input);while (getchar() != '\n');if (input == 1){printf("\n\t\t学生总数:%d", link_count(stu_head));student_showall(stu_head);}else if (input == 2){printf("\n\t\t课程总数:%d\n", link_count(cour_head));courseshowall_man(cour_head);}else if (input == 0)break;elseprintf("\n\t\t####输入错误!请重新输入!#####\n");}
}*/void courseshowone_man(course* ad)
{if (ad == NULL)printf("无课程");else{printf("\n\t\t------------------------------------------------------");printf("\n\t\t课程编号:%s\n", ad->num);printf("\t\t课程名称:%s\n", ad->name);printf("\t\t课程性质:%s\n", ad->nature);printf("\t\t开课学期:%s\n", ad->term);printf("\t\t总学时:%lf\n", ad->time_all);printf("\t\t授课学时:%lf\n", ad->time_teach);printf("\t\t实验或上机学时:%lf\n", ad->time_exp);printf("\t\t学分:%lf\n", ad->score);printf("\t\t已选学生人数:%d\n", ad->stu_sum);printf("\t\t已选学生:\n");printf("\n\t\t------------------------------------------------------");}
}void courseshowall_man(course* head)
{course* p;p = head;if (p == NULL){printf("\t\t无课程\n");return;}while (p != NULL){courseshowone_man(p);p = p->next;}
}void man_search_stu(student* head)
{while (1){printf("\n\t\t请输入学号或姓名进行查找,返回上级菜单请输入0000:");char input[50];scanf("%s", input);while (getchar() != '\n');if (strcmp(input, "0000") == 0)break;student* p_stu;if ((input[0] >= 48) && (input[0] <= 57))p_stu = studentnamefind_num(head, input);elsep_stu = studentnamefind_char(head, input);if (p_stu == stu_tail){printf("\n\t\t#####没有该学生的信息,请重新输入!#####/n");continue;}if (p_stu == NULL)p_stu = head;elsep_stu = p_stu->next;printf("\n\t\t该学生信息如下:");student_showone(p_stu);}
}
.student
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<malloc.h>
#include<ctype.h>
#include"student.h"extern student* stu_head;
extern course* cour_head;
extern course* cour_tail;
extern student* stu_tail;student* stu_login(student* head)
{student* copy_head = head;char input[100];printf("\t\t输入登录学号:");scanf("%s", input);while (getchar() != '\n');student* temp;temp = studentnamefind_num(head, input);if (temp == NULL)//the first studentreturn copy_head;else if ((temp != NULL) && (temp->next == NULL))//no such a studentreturn NULL;elsereturn temp->next;}int stu_menu()
{int n;printf("\n\t\t~~~~~~~~~~~学生菜单~~~~~~~~~~");printf("\n\t\t[1]:查询课程信息");printf("\n\t\t[2]:选课");printf("\n\t\t[3]:查询课表");printf("\n\t\t[4]退出\n");n = input_limit(4);return n;
}void coursechoose(course* head, student* stu)//选课函数
{int input;course* temp;if (stu->score_all <40|| stu->score_all >= 40 && stu->score_all <= 60){if (40 > stu->score_all)printf("\n\t\t你的总学分少于40,赶快去选课吧!\n");else{printf("\n\t\t你的学分为:%lf 大于40学分,继续选课输入1,停止选课输入0\n",stu->score_all);scanf("%d", &input);while (getchar() != '\n');if (input == 0)return;}while (1){printf("\n\t\t请输入[1]课程的性质 [2]学分进行选课 [3]返回上级菜单");int input;char innum[50];char inscor[50];scanf("%d", &input);while (getchar() != '\n');course* find = NULL;if (input == 1){courseshow_nature(head);printf("\n\t\t请输入所选课程编号:");scanf("%s", innum);find = coursenumfind_num(head, innum);}else if (input == 2){courseshow_score(head);printf("\n\t\t请输入所选课程编号:");scanf("%s", inscor);find = coursenumfind_num(head, inscor);}else if (input == 3)break;if (find == cour_tail){printf("\n\t\t#####该课程不存在!请重新输入#####\n");continue;}else if (find == NULL)find = head;elsefind = find->next;int judge = 0;for (int i = 0; i < stu->course_sum; i++){if (strcmp(stu->course[i], find->num) == 0){judge = 1; break;}temp = coursenumfind_num(head, stu->course[i]);temp = temp->next;if (strcmp(temp->term, find->term) == 0){judge = 1; break;}}if (judge == 1){printf("\n\t\t####该课程已经选择过了!或者时间重复####\n");continue;}else{stu->course_sum++;strcpy(stu->course[stu->course_sum - 1], find->num);stu->score_all += find->score;find->stu_sum++;printf("\n\t\t该课程选择成功!\n");}}}else{printf("\n\t\t总学分大于60,请删除部分课程!");stu_dele_cour(head, stu);}store_cour(cour_head);store_stu(stu_head);
}void courseshow_nature(course* head)
{course* p;char ad[MAXN];while (1){int flag = 0, sum = 0;p = head;printf("\n\t\t请输入要查找课程的性质,取消查找请输入0000:");scanf("%s", ad);while (getchar() != '\n');if (strcmp(ad, "0000") == 0)break;while (p != NULL){if (strcmp(ad, p->nature) == 0){course_showone(p);flag = 1;sum++;}p = p->next;}if (flag == 0)printf("\n\t\t没有该课程!####");}return;
}void courseshow_score(course* head)
{course* p;double ad;int flag, sum;while (1){flag = 0; sum = 0;p = head;printf("\n\t\t请输入要查找课程的学分,取消查找请输入0:");scanf("%lf", &ad);if (ad == 0)break;while (getchar() != '\n');while (p != NULL){if (ad == p->score){course_showone(p);flag = 1;sum++;}p = p->next;}if (flag == 0)printf("\n\t\t没有该课程!####");}return;
}void show_schedule(student* stu)
{course* p_head;for (int i = 0; i < stu->course_sum; i++){p_head = coursenumfind_num(cour_head, stu->course[i]);p_head = p_head->next;printf("\n\t\t % s % s % s % lf % lf % lf % lf % s % d\n", p_head->num, p_head->name, p_head->nature, p_head->time_all,p_head->time_teach, p_head->time_exp, p_head->score, p_head->term, p_head->stu_sum);}
}student* studentnamefind_char(student* head, char tar[])
{student* p, * q;p = head;q = NULL;while (p != NULL){if (strcmp(tar, p->name) == 0)return q;q = p;p = p->next;}return q;
}student* studentnamefind_num(student* head, char tar[])
{student* p, * q;p = head;q = NULL;while (p != NULL){if (strcmp(tar, p->num) == 0)return q;q = p;p = p->next;}return q;
}void student_showone(student* p)
{printf("\n\t\t------------------------------------------------------");printf("\n\t\t学号:%s", p->num);printf("\n\t\t姓名:%s", p->name);printf("\n\t\t学院与班级:%s", p->sch_cla);printf("\n\t\t密码:%s", p->password);if (p->course_sum == 0)printf("\n\t\t该学生无已选课程!\n");else{printf("\n\t\t已选课程:\n");for (int i = 0; i < p->course_sum; i++)printf("\t\t\t[%d]:%s\n", i + 1, p->course[i]);}printf("\t\t选课总数:%d", p->course_sum);printf("\n\t\t已选课程总学分:%lf", p->score_all);printf("\n\t\t------------------------------------------------------");
}
void student_showall(student* head)
{student* p;p = head;while (p != NULL){student_showone(p);p = p->next;}
}void stu_dele_cour(course* head, student* stu)
{while (1){printf("\n\t\t请输入需要删除课程的编号,返回上级菜单请输入0000:");char input[50];scanf("%s", input);while (getchar() != '\n');if (strcmp(input, "0000") == 0)break;int i = 0, result = -1;/*删除该学生记录中选课的信息*/for (; i < stu->course_sum; i++){if (strcmp(input, stu->course[i]) == 0){result = i; break;}}if (result == -1){printf("\n\t\t####你没有选择这门课程!请重新输入!"); continue;}strcpy(stu->course[result], stu->course[stu->course_sum - 1]);stu->course_sum--;course* find = coursenumfind_num(head, input);if (find == NULL)find = head;elsefind = find->next;/*删除该课程记录中学生的信息*/find->stu_sum--;printf("\n\t\t课程删除成功!\n");}store_stu(stu_head);store_cour(cour_head);
}