学生选课管理系统(工程实践)

.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;
	else
		return 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#####输入错误,请重新输入:");
		else
			break;
	}
	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;
		else
			printf("##### 输入错误!只能选择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();

				}
			}
			else
				printf("\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();
					}
				}
				else
					printf("\n\t\t~~~~~~~~~~~密码错误,重新登陆!~~~~~~~~~~");
			}
			else
				printf("\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;
			else
				printf("\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;
	else
		return 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;
			else
				printf("\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");
		}
		else
			printf("\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;
			else
				printf("\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;
			else
				find = 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;
			else
				printf("\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);
		else
			p = 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);
		}
		else
			printf("\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;
			else
				find = 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;
		else
			printf("\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);
		else
			p_stu = studentnamefind_char(head, input);

		if (p_stu == stu_tail)
		{
			printf("\n\t\t#####没有该学生的信息,请重新输入!#####/n");
			continue;
		}

		if (p_stu == NULL)
			p_stu = head;
		else
			p_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 student
		return copy_head;
	else if ((temp != NULL) && (temp->next == NULL))//no such a student
		return NULL;
	else
		return 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;
			else
				find = 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;
		else
			find = find->next;

		/*删除该课程记录中学生的信息*/
		find->stu_sum--;

		printf("\n\t\t课程删除成功!\n");
	}

	store_stu(stu_head);
	store_cour(cour_head);
}

 

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值