C语言课程设计——学生管理系统(链表实现)

此代码为我大一课设时所写,编译环境为visual studio 2017,其中scanf已不安全,因此会报有警告错误,可忽视,文件除下述5个.c文件外,与之同目录的还应有stu.txt,user.txt,vistor.txt等三个文件,其中初始内容为空。
下述为实验报告与代码,也可直接下载查看,下载内容与下述内容基本一致,链接为:https://download.csdn.net/download/weixin_45693492/12547370

设计目的

使用链表实现简单的学生信息管理功能,在实现过程中不用全局变量,登录分为管理员登录与学生登录,二者登陆后可执行不同的操作。管理员需注册后方可登录,登陆后可对学生信息进行添加,修改,删除,查询,浏览(排序后显示),以及排名信息查看;学生登录后可查看自己的信息,修改除学号、成绩以外的信息,查看排名时自己的信息为红色,修改自己登录密码。

设计内容

  1. 链表的创建
  2. 链表的修改
  3. 链表的删除
  4. 链表的排序
  5. 打印报表
  6. 将学生信息保存至磁盘文件中
  7. 从磁盘文件读取学生信息
  8. 限制输入(如注册账号时输入除字母、数字、下划线外的字符无用)
  9. 录入字符显示“*”
  10. 使局部文字变色

概要设计

  1. 登录界面
    C语言课程设计——学生管理系统(链表实现)_第1张图片
  2. 管理员界面
    C语言课程设计——学生管理系统(链表实现)_第2张图片
  3. 学生登录界面
    C语言课程设计——学生管理系统(链表实现)_第3张图片

详细设计

  1. 管理员注册:注册管理员账号与密码(输入过程中可删除)。管理员的账号由字母、数字和下划线组成,不合法的用户名无法注册成功。
    C语言课程设计——学生管理系统(链表实现)_第4张图片

  2. 管理员(学生登录):输入正确的账号与密码才能进入。管理员登录后可对学生信息进行添加、修改、删除、浏览、查询以及排名查看。学生登录成功在菜单界面会显示该学生的学号,可查看个人信息,修改个人户籍信息,修改密码,查看排名。

  3. 添加学生信息:录入前会读取文件中是否有学生信息,在录入时会显示录入的为第几个学生;录入学号、出生日期、联系方式时需按照要求录入,录入非法数据会提示重新录入;录入学生的信息,会自动生成学生账号与密码(账号与初始密码均为学号)。

C语言课程设计——学生管理系统(链表实现)_第5张图片

  1. 修改学生信息:可按姓名或学号查找学生信息,修改学生的信息是会显示原学生信息,学号修改学生账号与密码会初始化(新密码为新学号)。

C语言课程设计——学生管理系统(链表实现)_第6张图片

  1. 删除学生信息:可按姓名或学号查找学生信息,删除学生的信息时,会显示该学生信息,删除后学生账号与密码也会删除。

C语言课程设计——学生管理系统(链表实现)_第7张图片
6. 浏览学生信息:可浏览的学生的的成绩信息(按成绩排序)、户籍信息(按学号排序)以及现有学生账号与密码,每进入某一模块会重新排序,学生账号保存于另一文件,不进行排序。
C语言课程设计——学生管理系统(链表实现)_第8张图片
7. 查找学生信息:可按姓名或学号查找学生信息,显示学生全部信息。
C语言课程设计——学生管理系统(链表实现)_第9张图片

  1. 学生排名信息:按成绩给学生A、B、C、D四个评价,可查看高数、C语言、英语、总成绩等排名,各个模块按成绩排序,成绩相同按学号排序。当学生登陆查看时,自己的信息会变红色。
    C语言课程设计——学生管理系统(链表实现)_第10张图片
  2. 修改密码:修改学生密码。当三次输错原密码,将会退出学生登录,须重新登录方可进行操作,当修改成功后也会退出登录,须重新登录。
    C语言课程设计——学生管理系统(链表实现)_第11张图片

测试数据及运行结果

  1. 管理员注册
    C语言课程设计——学生管理系统(链表实现)_第12张图片
  2. 管理员登录
    C语言课程设计——学生管理系统(链表实现)_第13张图片
  3. 数据录入
    C语言课程设计——学生管理系统(链表实现)_第14张图片
  4. 数据修改
    C语言课程设计——学生管理系统(链表实现)_第15张图片
    C语言课程设计——学生管理系统(链表实现)_第16张图片
  5. 数据删除
    C语言课程设计——学生管理系统(链表实现)_第17张图片
  6. 数据查询
    C语言课程设计——学生管理系统(链表实现)_第18张图片
  7. 数据浏览

C语言课程设计——学生管理系统(链表实现)_第19张图片
C语言课程设计——学生管理系统(链表实现)_第20张图片
C语言课程设计——学生管理系统(链表实现)_第21张图片
8. 学生登录(菜单会显示学生学号)
C语言课程设计——学生管理系统(链表实现)_第22张图片
9. 学生排名信息(按各科成绩排序,不显示分数,只显示分数对应的评价)
C语言课程设计——学生管理系统(链表实现)_第23张图片
在这里插入图片描述
在这里插入图片描述
10. 修改密码
C语言课程设计——学生管理系统(链表实现)_第24张图片
C语言课程设计——学生管理系统(链表实现)_第25张图片

调试情况,设计技巧及体会

调试情况:
在最开始,从文件读取数据时只有成功时才返回一个链表的头节点,导致当未录入数据时,或未建立存储信息的文本文件时,总是显示读出有错,之后我让未建立文本文件或未存储学生信息时也返回链表的头指针,不过头结点的指针域指向空。这样可以通过判断指针域的情况判断文件是否有数据。
在用户登录时,用来存储用户名的字符数组大小是固定的,管理员为0-20,学生为8位,当登录时如果录入的字符串超过字符数组的大小,程序就会出错,所以当录入字符串超过字符数组大小时,就用do…while函数令其重新录入,当满足条件后方可输入密码。
在添加学生信息时,我本来用的是以追加的形式写,但最后发现进行修改、删除操作时不能以追加的形式写文件,否则之前的数据还会在,所以我改成了以写的方式写文件,先用链表将数据读出来,再用尾插法插入新数据,最后保存链表。
设计技巧:

  1. 用户名录入
int legal_user(char ch)         //限制用户名的字符
{
if (((48 <= ch && ch <= 57) || (65 <= ch && ch <= 90) || (97 <= ch && ch <= 122) || ch == '\r' || ch == '\b'||ch=='_'))
			return 1;
		else
			return 0;
}
//录入用户名时若不是数字、字母、下划线、删除或回车,需要重新录入
do {
			ch = getch();		
		} while (legal_user(ch) != 1);
  1. 密码变“*”
for (i = 0; i < 12; i++)
{
do {	
				ch = getch();								
			} while (legal_pass(ch) != 1);	//密码不合法重新录入
			//未录入数据时按回车或删除键重新录入
			if (i == 0 && (ch == '\b' || ch == '\r'))
			{
				i--;
			}
			//有数据时,按下回车键退出录入密码
			else if (i > 0 && ch == '\r')
			{
				break;
			}
/*有数据时按下删除键光标移至前一字符处,用空格覆盖该字符,再移至前一字符处*/
			else if (i > 0 && ch == '\b')
			{
				printf("\b \b");
				pass[i] = '\0';
				i -= 2;
			}
           //打印“*”,将ch中数据存入密码字符串中
			else
			{
				printf("*");
				pass[i] = ch;
			}
}
//令最后一个字符为结束符
pass[i] = '\0';
  1. 链表排序
tail = NULL; 
	pre = head;
   //链表第一个数据不指向tail时执行循环
	while ((head->next->next) != tail)
	{
       //p为第一个数据域
		p = head->next;
		pre = head;
        //p->next不指向tail时执行循环
		while (p->next != tail)
		{
           //比较大小
			if (p->score.ave< p->next->score.ave)
			{
				pre->next = p->next;
				temp = p->next->next;
				p->next->next = p;
				p->next = temp;
				p = pre->next;      //p向前移一个节点
			}
			p = p->next; 			  //p向后移一个节点 
			pre = pre->next;
		}
		tail = p;
	}
  1. 字体变色
HANDLE fontcolor;
	fontcolor = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(fontcolor, FOREGROUND_RED);//设置字体为红色

体会:
通过这次课设,我受益匪浅,亲身体验了软件系统设计的全过程。在实践中了解了软件开发设计的步骤、流程及思路。增长了在软件开发方面的见识。我深刻认识到以前基础的重要性,也使我掌握了一些课外的知识。我现在更加熟练地使用链表,学会了如何录入一个字符让屏幕打印“*”。现在这个程序的功能还不是很多,我之后将好好学习专业知识,做一个更加完善的课设。

代码:

//main.c
#include "data.c"
#include "file.c"
#include "user.c"
#include "student.c"

//打印登录菜单
void print_login_menu()
{
	system("cls");
	printf("\n\n                  ");
	printf("/*======================学生信息管理系统======================*/\n                  ");
	printf("/*                                                            */\n                  ");
	printf("/*                        1.管理员登录                        */\n                  ");
	printf("/*                                                            */\n                  ");
	printf("/*                        2.学生登录                          */\n                  ");
	printf("/*                                                            */\n                  ");
	printf("/*                        3.管理员注册                        */\n                  ");
	printf("/*                                                            */\n                  ");
	printf("/*                        0.退出系统                          */\n                  ");
	printf("/*                                                            */\n                  ");
	printf("/*============================================================*/\n                  ");
	printf("请输入要选择的功能(0-3):");
}

//限制管理员账号只能为字母或数字或下划线
int legal_user(char ch) 
{
	if (((48 <= ch && ch <= 57) || (65 <= ch && ch <= 90) || (97 <= ch && ch <= 122) || ch == '\r' || ch == '\b'||ch=='_'))
		return 1;
	else
		return 0;
}

//限制密码只能为字母或数字
int legal_pass(char ch)
{
	if (((48 <= ch && ch <= 57) || (65 <= ch && ch <= 90) || (97 <= ch && ch <= 122) || ch == '\r' || ch == '\b'))
		return 1;
	else
		return 0;
}



//注册管理员账号
void account_user(users *temp)
{
	users *head, *user;
	int i,flag=2,count;
	char ch;
	head = read_user();
		while (flag != 0)
		{
			printf("\n\n                  请输入用户账号(0-18):");
			if (flag == 1)
			{
				printf("\n                  此账号已注册过,请重新输入账号!\n");
				printf("\n                  请重新输入用户账号(0-18):");
			}
			flag = 0;
			count = 0;
			do {
				if (count != 0)
					printf("\n                  请重新输入用户账号(0-18):");
				for (i = 0; i < 18; i++)							
				{
					do {
						ch = getch();								
					} while (legal_user(ch) != 1);
					if (i == 0 && ch == '\r')
					{
						printf("\n                  请输入账号后再按回车键!\n");
						printf("\n                  请重新输入用户账号(0-18):");
						i--;
					}
					else if (i > 0 && ch == '\r')
					{
						break;
					}
					else if (i == 0 && ch == '\b')
					{
						i--;
						continue;
					}
					else if (i > 0 && ch == '\b')
					{
						printf("\b \b");
						temp->user[i] = '\0';
						i -= 2;
					}
					else
					{
						printf("%c", ch);
						temp->user[i] = ch;
					}
				}
				temp->user[i] = '\0';
				count++;
			} while (ch != '\r');
			for (user = head->next; user != NULL; user = user->next)
			{
				if (strcmp(user->user, temp->user) == 0)
				{
					flag = 1;
					i = 0;
					break;
				}
			}
		}
	count = 0;
	do {
		if (count == 0)
			printf("\n                  请输入用户密码(6-12):");
		else
			printf("\n                  请重新输入密码(6-12):");
		for (i = 0; i < 12; i++)
		{
			do {
				ch = getch();								
			} while (legal_pass(ch) != 1);
			if (i == 0 && ch == '\r')
			{
				printf("\n                  请输入密码后再按回车键!\n");
				printf("\n                  请重新输入用户密码(6-12):");
				i--;
			}

			else if (i < 6 && ch == '\r')
			{
				printf("\n                  请输入6-12位密码(6-12):");
				i = 0;
			}
			else if (i >= 6 && ch == '\r')
			{
				break;
			}
			else if (i == 0 && ch == '\b')
			{
				i--;
				continue;
			}
			else if (i > 0 && ch == '\b')
			{
				printf("\b \b");
				temp->passward[i] = '\0';
				i -= 2;
				continue;
			}
			else
			{
				printf("*");
				temp->passward[i] = ch;
			}
		}
		temp->passward[i] = '\0';
		count++;
	} while (ch != '\r');
}

//注册管理员账号(选择是否保存,是否继续注册)
void user_account()
{
	users *head, *pass, *temp;
	char choice;
	head = (users *)malloc(sizeof(users));
	head->next = NULL;
	pass = head;
	{
		do 
		{
			temp = (users *)malloc(sizeof(users));
			account_user(temp);
			temp->next = pass->next;
			pass->next = temp;
			pass = temp;
			printf("\n                  账号注册成功,是否保存?(Y/N)");
			do
			{
				choice = getch();
			} while (choice != 'y' && choice != 'Y' && choice != 'N' && choice != 'n');
			if (choice == 'y' || choice == 'Y')
				save_user(head);
			if (choice == 'y' || choice == 'Y')
				printf("\n                  账号保存成功,是否继续注册?(Y/N)");
			else
				printf("\n                  已放弃保存账号,是否继续注册?(Y/N)");
			do
			{
				choice = getch();
			} while (choice != 'y' && choice != 'Y' && choice != 'N' && choice != 'n');
		} while (choice == 'Y' || choice == 'y');
	}
	
}

//管理员登录
void user_login()
{
	users *head, *temp;
	int i,flag;
	char ch,choice;
	char user[20],pass[13];
	head = read_user();
	do
	{
		system("cls");
		printf("\n\n                                      管理员登录");
		do {
		printf("\n\n                                账号(0-20):");
		scanf("%s", user);
		} while (strlen(user) > 20);
		printf("\n                                密码:");
		for (i = 0; i < 12; i++)
		{
			do {
				ch = getch();								
			} while (legal_pass(ch) != 1);
			if (i == 0 && (ch == '\b' || ch == '\r'))
			{
				i--;
			}
			else if (i > 0 && ch == '\r')
			{
				break;
			}
			else if (i > 0 && ch == '\b')
			{
				printf("\b \b");
				pass[i] = '\0';
				i -= 2;
			}
			else
			{
				printf("*");
				pass[i] = ch;
			}
		}
		pass[i] = '\0';
		flag = 0;
		for (temp = head->next; temp != NULL; temp = temp->next)
		{
			if (strcmp(temp->user, user) == 0 && strcmp(temp->passward, pass) == 0)
			{
				flag = 1;
				break;
			}
		}
		if (flag == 0)
		{
			printf("\n\n                                用户名不存在或密码错误!");
			printf("\n                                是否重新登录?(Y/N)");
			do
			{
				choice = getch();
			} while (choice != 'y' && choice != 'Y' && choice != 'N' && choice != 'n');
		}
	} while ((choice == 'Y' || choice == 'y')&&flag==0);
	if (flag == 1)
	{
		printf("\n                                正在登录");
		for (i = 0; i < 7; i++)
		{
			printf(".");
			Sleep(200);
		}
		printf("\n                                登录成功!");
		getch();
		select_user_menu();
	}
}

//在登录界面进行操作
void select_login()
{
	char ch;

	while (1)
	{
		system("cls");
		print_login_menu();
		do
		{
			ch = getch();
		} while (ch<48 || ch>51);
		system("cls");
		switch (ch)
		{
		case 49:    user_login();
			break;
		case 50:    stu_login();
			break;
		case 51:    user_account();
			break;
		case 48: return;
			break;
		default:
			break;
		}
	}
}

int main()
{
	select_login();
	return 0;
}

/*******************************************
文件名:data.c
功  能:声明头文件、函数、结构体。
********************************************/

#include 
#include 
#include 
#include 
#include 


/********************************结构体**********************************/
//学生成绩结构体
typedef struct mark
{
	float math;							//高数
	float c_language;					//C语言
	float english;						//英语
	float all;							//总成绩
	float ave;							//平均成绩
}mark;

//学生成绩评价结构体
typedef struct test
{
	char math;							//高数
	char c_language;					//C语言
	char english;						//英语
	char all;							//总成绩
}test;

//出生日期结构体
typedef struct date
{
	int year;
	int month;
	int day;
}date;

//学生信息结构体
typedef struct student
{
	char id[10];						//学号
	char name[20];						//姓名
	char sex[3];						//性别
	int age;							//年龄
	date birthday;						//出生日期
	mark score;							//成绩
	test grade;							//评分等级
	char addr[50];						//地址
	char phone[13];							//手机号码
	struct student *next;
}student;

//管理员账号密码结构体
typedef struct users
{
	char user[20];
	char passward[13];
	struct users *next;
}users;

//学生账号密码结构体
typedef struct vistor
{
	char id[10];
	char passward[13];
	struct vistor *next;
}vistor;

/********************************函数声明**********************************/
//data.c
char grade_assess(float n);             //对分数进行评价
student *create_stu();                  //创建学生信息(学生个人信息及登录账号与密码)
void print_stu(student *stu);           //打印单个学生信息
void score_sort(student *head);         //按总成绩对学生进行排序,由大到小,成绩相同学号小的在前
void id_sort(student *head);            //按学号对学生进行排序,由小到大
void grade_math_sort(student *head);    //按高数成绩对学生进行排序,由大到小,成绩相同学号小的在前
void grade_c_sort(student *head);       //按C语言成绩对学生进行排序,由大到小,成绩相同学号小的在前
void grade_english_sort(student *head); //按英语成绩对学生进行排序,由大到小,成绩相同学号小的在前
void print_grade_menu();                //打印学生排名菜单
//file.c
void save_stu(student *head);        //将学生信息保存至磁盘文件中
student *read_stu();                 //从磁盘文件中读取学生信息
void save_vistor(vistor *head);      //将学生密码与账号保存至磁盘文件中
vistor *read_vistor();               //从磁盘文件读取学生账号与密码
void print_vis();                    //打印学生账号与密码
void save_user(users *head);         //将管理员账号与密码保存至磁盘文件中
users *read_user();                  //从磁盘文件中读取管理员账号与密码
//student.c
void key(char id[]);                //修改学生密码
void search_stu(char id[]);         //按学号查找学生信息并打印
void print_stu_menu(char id[]);     //打印学生登录菜单
void print_modify_stu();            //打印修改学生信息菜单(学生修改)
void modify_stu(char id[]);         //学生修改自己信息
void select_stu_menu(char id[]);    //对学生登录界面进行操作
void stu_login();                   //学生登录
void select_grade_stu(char id[]);   //查看学生排名(学生查看,自己的信息为红色)
//user.c
void print_user_menu();		           //管理员登录菜单			
void select_user_menu();		       //对学生信息进行管理
void print_modify_menu();			   //打印修改学生信息方式菜单(按学号查找修改、按姓名查找修改)
void select_modify();                  //选择修改学生信息的方式(按学号查找修改、按姓名查找修改)
void modify_choices();                 //打印修改学生信息菜单
void modify(student *stu);             //修改学生信息(管理员修改,可修改学生学)
void print_del_menu();                 //打印删除菜单
void select_del();                     //删除学生信息(学生信息删除,学生账号、密码也会被删除)
void print_search_menu();              //打印查找学生信息菜单
void select_search();                  //查找学生信息
void print_watch_menu();               //打印浏览学生信息菜单(可查看学生账号密码)
void select_watch();                   //浏览学生信息
void select_grade();                   //查看学生排名(可查看各科成绩排名)
//main.c
void print_login_menu();          //打印登录菜单
int legal_user(char ch);          //限制管理员账号只能为字母或数字或下划线
int legal_pass(char ch);          //限制密码只能为字母或数字
void account_user(users *temp);   //注册管理员账号
void user_account();              //注册管理员账号(选择是否保存,是否继续注册)
void user_login();                //管理员登录
void select_login();              //在登录界面进行操作

//对分数进行评价
char grade_assess(float n)
{
	if (90 <= n && n <= 100)
		return 'A';
	else if (80 <= n && n < 90)
		return 'B';
	else if (60 <= n && 80 < 90)
		return 'C';
	else if (0 <= n && n < 60)
		return 'D';
	else
	{
		printf("成绩错误!\n");
		return 0;
	}
}

//创  建学生信息(学生个人信息及登录账号与密码)
student *create_stu()
{
	student *head,  *stu, *head1, *stu1;
	vistor *v_head, *vis;
	int i, flag;
	char choice;
	do
	{
		head = read_stu();
		v_head = read_vistor();
		head1 = read_stu();
		for (stu1 = head1->next, i = 0; stu1 != NULL; stu1 = stu1->next)
			i++;
		flag = 1;
		system("cls");
		stu = (student *)malloc(sizeof(student));
		vis = (vistor *)malloc(sizeof(vistor));
		printf("\n\n第%d个人的信息:\n", ++i);
		printf("\n学号(8位):");
		scanf("%s", stu->id);
		while (flag == 1 || strlen(stu->id) != 8)
		{
			flag = 0;
			if (strlen(stu->id) != 8)
			{
				printf("\n请输入8位学号:");
				scanf("%s", stu->id);
			}
			for (stu1 = head1->next; stu1 != NULL; stu1 = stu1->next)
				if (strcmp(stu1->id, stu->id) == 0)
				{
					flag = 1;
					printf("此学号已存在,请重新录入!\n");
					printf("\n学号(8位):");
					scanf("%s", stu->id);
				}
		}
		strcpy(vis->id, stu->id);
		strcpy(vis->passward, stu->id);
		printf("\n姓名:");
		scanf("%s", stu->name);
		printf("\n性别(男/女):");
		scanf("%s", stu->sex);
		printf("\n年龄:");
		scanf("%d", &stu->age);
		printf("\n出生日期(例xxxx.xx.xx):");
		scanf("%d.%d.%d", &stu->birthday.year, &stu->birthday.month, &stu->birthday.day);
		while (!(0 < stu->birthday.year && 0 < stu->birthday.month&&stu->birthday.month <= 12 && 0 < stu->birthday.day&&stu->birthday.day <= 31))
		{
			printf("\n请输入正确的日期:");
			scanf("%d.%d.%d", &stu->birthday.year, &stu->birthday.month, &stu->birthday.day);
		}
		stu->score.all = 0;
		stu->score.ave = 0;
		printf("\n高数成绩(0-100):");
		scanf("%f", &stu->score.math);
		while (!(0 <= stu->score.math&& stu->score.math <= 100))
		{
			printf("\n请输入正确的成绩:");
			scanf("%f", &stu->score.math);
		}
		stu->grade.math = grade_assess(stu->score.math);
		printf("\nC语言成绩(0-100):");
		scanf("%f", &stu->score.c_language);
		while (!(0 <= stu->score.c_language && stu->score.c_language <= 100))
		{
			printf("\n请输入正确的成绩:");
			scanf("%f", &stu->score.c_language);
		}
		stu->grade.c_language = grade_assess(stu->score.c_language);
		printf("\n英语成绩(0-100):");
		scanf("%f", &stu->score.english);
		while (!(0 <= stu->score.english && stu->score.english <= 100))
		{
			printf("\n请输入正确的成绩:");
			scanf("%f", &stu->score.english);
		}
		stu->grade.english = grade_assess(stu->score.english);
		stu->score.all = stu->score.math + stu->score.c_language + stu->score.english;
		stu->score.ave = stu->score.all / 3;
		stu->grade.all = grade_assess(stu->score.ave);
		printf("\n地址:");
		scanf("%s", stu->addr);
		printf("\n联系方式(11位):");
		scanf("%s", stu->phone);
		while (strlen(stu->phone) != 11)
		{
			printf("\n请输入正确的手机号码:");
			scanf("%s", stu->phone);
		}

		stu->next = head->next;
		head->next = stu;						//尾插新结点
		vis->next = v_head->next;
		v_head->next = vis;
		printf("\n是否保存学生信息?(Y/N)");
		do
		{
			choice = getch();
		} while (choice != 'y' && choice != 'Y' && choice != 'N' && choice != 'n');
		if (choice == 'N' || choice == 'n')
			printf("\n已放弃保存,是否继续录入?(Y/N)");
		else 
		{
			save_stu(head);
			save_vistor(v_head);
			printf("\n文件保存成功,是否继续录入?(Y/N)");
		}
		do
		{
			choice = getch();
		} while (choice != 'y' && choice != 'Y' && choice != 'N' && choice != 'n');
	} while (choice == 'Y' || choice == 'y');
	return head;
}

//打印单个学生信息
void print_stu(student *stu)
{
	printf("\n                  学    号:%s", stu->id);
	printf("\n                  姓    名:%s", stu->name);
	printf("\n                  性    别:%s", stu->sex);
	printf("\n                  年    龄:%d", stu->age);
	printf("\n                  出生日期:%4d.%2d.%2d", stu->birthday.year, stu->birthday.month, stu->birthday.day);
	printf("\n                  高   数:%3.1f\t", stu->score.math);
	printf("C 语 言:%3.1f\t", stu->score.c_language);
	printf("英   语:%3.1f\t", stu->score.english);
	printf("平均成绩:%3.1f\t", stu->score.ave);
	printf("总 成 绩:%3.1f", stu->score.all);
	printf("\n                  联系方式:%s", stu->phone);
	printf("\n                  地    址:%s\n", stu->addr);
}

//按总成绩对学生进行排序,由大到小,成绩相同学号小的在前
void score_sort(student *head)   
{							
	student *pre, *p, *tail, *temp;
	tail = NULL;
	pre = head;

	while ((head->next->next) != tail)
	{
		p = head->next;
		pre = head;
		while (p->next != tail)
		{
			if (p->score.ave< p->next->score.ave)

			{
				pre->next = p->next;
				temp = p->next->next;
				p->next->next = p;
				p->next = temp;
				p = pre->next;  

			}
			else if (p->score.ave == p->next->score.ave)
			{
				if (strcmp(p->id, p->next->id) > 0)
				{
					pre->next = p->next;
					temp = p->next->next;
					p->next->next = p;
					p->next = temp;
					p = pre->next;  
				}
			}
			p = p->next;  
			pre = pre->next;
		}
		tail = p;
	}
}

//按学号对学生进行排序,由小到大
void id_sort(student *head)  
{							
	student *pre, *p, *tail, *temp;
	tail = NULL;
	pre = head;

	while ((head->next->next) != tail)
	{
		p = head->next;
		pre = head;
		while (p->next != tail)
		{
			if (strcmp(p->id, p->next->id) > 0)

			{
				pre->next = p->next;
				temp = p->next->next;
				p->next->next = p;
				p->next = temp;
				p = pre->next;  

			}
			p = p->next; 
			pre = pre->next;
		}
		tail = p;
	}
}

//按高数成绩对学生进行排序,由大到小,成绩相同学号小的在前
void grade_math_sort(student *head)  
{							
	student *pre, *p, *tail, *temp;
	tail = NULL;
	pre = head;

	while ((head->next->next) != tail)
	{
		p = head->next;
		pre = head;
		while (p->next != tail)
		{
			if (p->score.math<p->next->score.math)

			{
				pre->next = p->next;
				temp = p->next->next;
				p->next->next = p;
				p->next = temp;
				p = pre->next; 

			}
			else if (p->score.math == p->next->score.math)
			{
				if (strcmp(p->id, p->next->id) > 0)
				{
					pre->next = p->next;
					temp = p->next->next;
					p->next->next = p;
					p->next = temp;
					p = pre->next; 
				}
			}
			p = p->next;  //stu再前进一个节点 
			pre = pre->next;
		}
		tail = p;
	}
}

//按C语言成绩对学生进行排序,由大到小,成绩相同学号小的在前
void grade_c_sort(student *head)   
{							
	student *pre, *p, *tail, *temp;
	tail = NULL;
	pre = head;

	while ((head->next->next) != tail)
	{
		p = head->next;
		pre = head;
		while (p->next != tail)
		{
			if (p->score.c_language<p->next->score.c_language)

			{
				pre->next = p->next;
				temp = p->next->next;
				p->next->next = p;
				p->next = temp;
				p = pre->next;  
			}
			else if (p->score.c_language == p->next->score.c_language)
			{
				if (strcmp(p->id, p->next->id) > 0)
				{
					pre->next = p->next;
					temp = p->next->next;
					p->next->next = p;
					p->next = temp;
					p = pre->next;  
				}
			}
			p = p->next;  
			pre = pre->next;
		}
		tail = p;
	}
}

//按英语成绩对学生进行排序,由大到小,成绩相同学号小的在前
void grade_english_sort(student *head)   
{							//排序中没有修改头节点指针值,只是修改指针内容head->next的值 
	student *pre, *p, *tail, *temp;
	tail = NULL;
	pre = head;

	while ((head->next->next) != tail)
	{
		p = head->next;
		pre = head;
		while (p->next != tail)
		{
			if (p->score.english<p->next->score.english)

			{
				pre->next = p->next;
				temp = p->next->next;
				p->next->next = p;
				p->next = temp;
				p = pre->next; 
			}
			else if (p->score.english == p->next->score.english)
			{
				if (strcmp(p->id, p->next->id) > 0)
				{
					pre->next = p->next;
					temp = p->next->next;
					p->next->next = p;
					p->next = temp;
					p = pre->next; 
				}
			}
			p = p->next;  
			pre = pre->next;
		}
		tail = p;
	}
}

//打印学生排名菜单
void print_grade_menu()
{
	system("cls");
	printf("\n\n                  ");
	printf("/*======================学生排名信息======================*/\n                  ");
	printf("/*                                                        */\n                  ");
	printf("/*                      1.高数排名                        */\n                  ");
	printf("/*                                                        */\n                  ");
	printf("/*                      2.C语言排名                       */\n                  ");
	printf("/*                                                        */\n                  ");
	printf("/*                      3.英语排名                        */\n                  ");
	printf("/*                                                        */\n                  ");
	printf("/*                      4.总分排名                        */\n                  ");
	printf("/*                                                        */\n                  ");
	printf("/*                      0.返回主菜单                      */\n                  ");
	printf("/*                                                        */\n                  ");
	printf("/*========================================================*/\n                  ");
	printf("请输入要选择的功能(0-4):");
}
/*******************************************
文件名:file.c
功  能:与文件保存与读取有关的函数。
********************************************/

//将学生信息保存至磁盘文件中
void save_stu(student *head)
{
	student *stu;
	FILE *fp;
	if ((fp = fopen("stu.txt", "wb")) == NULL)
	{
		printf("                  写文件出现错误,按任意键退出!");
		getch();
		exit(1);
	}
	for (stu = head->next; stu != NULL; stu = stu->next)
		fwrite(stu, sizeof(student), 1, fp);
	fclose(fp);
}

//从磁盘文件中读取学生信息
student *read_stu()
{
	student *head, *p, *stu;
	FILE *fp;
	head = (student *)malloc(sizeof(student));
	head->next = NULL;
	if ((fp = fopen("stu.txt", "rb")) == NULL)
		return head;
	p = head;
	stu = (student *)malloc(sizeof(student));
	while (fread(stu, sizeof(student), 1, fp))
	{
		stu->next = p->next;
		p->next = stu;
		p = stu;
		stu = (student *)malloc(sizeof(student));
	}
	p->next = NULL;
	fclose(fp);
	return head;
}

//将学生密码与账号保存至磁盘文件中
void save_vistor(vistor *head)
{
	FILE *fp;
	vistor *temp;
	if ((fp = fopen("vistor.txt", "wb")) == NULL)
	{
		printf("                  写文件出现错误,按任意键退出!");
		getch();
		exit(1);
	}
	for (temp = head->next; temp != NULL; temp = temp->next)
		fwrite(temp, sizeof(vistor), 1, fp);
	fclose(fp);
}

//从磁盘文件读取学生账号与密码
vistor *read_vistor()
{
	vistor *head, *temp, *pass;
	FILE *fp;
	head = (vistor *)malloc(sizeof(vistor));
	head->next = NULL;
	if ((fp = fopen("vistor.txt", "rb")) == NULL)
	{
		return head;
	}
	temp = head;
	pass = (vistor *)malloc(sizeof(vistor));
	while (fread(pass, sizeof(vistor), 1, fp))
	{
		pass->next = temp->next;
		temp->next = pass;
		temp = pass;
		pass = (vistor *)malloc(sizeof(vistor));
	}
	temp->next = NULL;
	fclose(fp);
	return head;
}

//打印学生账号与密码
void print_vis()
{
	vistor *head,*vis;
	head = read_vistor();
	system("cls");
	printf("\n\n                                               学生密码\n\n");
	for (vis = head->next; vis != NULL; vis = vis->next)
	{
		printf("                                账号:%-15s密码:%s\n", vis->id, vis->passward);
	}
}

//将管理员账号与密码保存至磁盘文件中
void save_user(users *head)
{
	FILE *fp;
	users *temp;
	if ((fp = fopen("user.txt", "ab")) == NULL)
	{
		printf("                  写文件出现错误,按任意键退出!");
		getch();
		exit(1);
	}
	for (temp = head->next; temp != NULL; temp = temp->next)
		fwrite(temp, sizeof(users), 1, fp);
	fclose(fp);
}

//从磁盘文件中读取管理员账号与密码
users *read_user()
{
	users *head, *temp, *pass;
	FILE *fp;
	head = (users *)malloc(sizeof(users));
	head->next = NULL;
	if ((fp = fopen("user.txt", "rb")) == NULL)
	{
		return head;
	}
	temp = head;
	pass = (users *)malloc(sizeof(users));
	while (fread(pass, sizeof(users), 1, fp))
	{
		pass->next = temp->next;
		temp->next = pass;
		temp = pass;
		pass = (users *)malloc(sizeof(users));
	}
	temp->next = NULL;
	fclose(fp);
	return head;
}

/*******************************************
文件名:student.c
功  能:与学生操作有关的函数。
********************************************/

//修改学生密码
void key(char id[])
{
	char pass[50];
	int i,count,flag=0;
	char ch;
	vistor *head, *vis;
	head = read_vistor();
	for (vis = head->next; vis != NULL; vis = vis->next)
		if (strcmp(vis->id, id) == 0)
			break;
	printf("\n\n                                            修改密码\n\n\n");
	while(1)
	{
		printf("\n                                请输入旧密码(6-12):");
		scanf("%s", pass);
		if (strcmp(vis->passward, pass) != 0)
		{
			printf("\n                                密码错误");
			flag++;
		}
		else
			break;
		if (flag >= 3)
		{
			printf("\n                                密码三次输错,3秒后将退出登录!");
			printf("\n                                退出中:");
			for (i = 0; i < 7; i++)
			{
				printf(".");
				Sleep(400);
			}
			return;
		}
	}
	count = 0;
	do {
		if (count == 0)
			printf("\n                                请输入新密码(6-12):");
		else
			printf("\n                                请正确输入密码(6-12):");
		for (i = 0; i < 12; i++)
		{
			do {
				ch = getch();								//获取键盘消息
			} while (!((48 <= ch && ch <= 57) || (65 <= ch && ch <= 90) || (97 <= ch && ch <= 122) || ch == '\r' || ch == '\b'));
			if (i == 0 && ch == '\r')
			{
				printf("\n                                请输入密码后再按回车键!\n");
				printf("\n                                请正确输入新密码(6-12):");
				i--;
			}

			else if (i < 6 && ch == '\r')
			{
				printf("\n                                请输入6-12位密码(6-12):");
				i = 0;
			}
			else if (i >= 6 && ch == '\r')
			{
				break;
			}
			else if (i == 0 && ch == '\b')
			{
				i--;
				continue;
			}
			else if (i > 0 && ch == '\b')
			{
				printf("\b \b");
				vis->passward[i] = '\0';
				i -= 2;
				continue;
			}
			else
			{
				printf("*");
				vis->passward[i] = ch;
			}
		}
		vis->passward[i] = '\0';
		count++;
	} while (ch != '\r');
	save_vistor(head);
	printf("\n                                密码修改成功,3秒后请重新登录!");
	printf("\n                                退出中:");
	for (i = 0; i < 7; i++)
	{
		printf(".");
		Sleep(400);
	}
	return;
}

//按学号查找学生信息并打印
void search_stu(char id[])
{
	student *head, *stu;
	head = read_stu();
	for (stu = head->next; stu != NULL; stu = stu->next)
		if (strcmp(stu->id, id) == 0)
		{
			print_stu(stu);
			break;
		}
	printf("\n                  按任意键退出!\n");
	getch();
}

//打印学生登录菜单
void print_stu_menu(char id[])
{
	system("cls");
	printf("\n\n                  ");
	printf("/*=====================%s,欢迎登录!=====================*/\n                  ", id);
	printf("/*                                                            */\n                  ");
	printf("/*                        1.查看信息                          */\n                  ");
	printf("/*                                                            */\n                  ");
	printf("/*                        2.修改信息                          */\n                  ");
	printf("/*                                                            */\n                  ");
	printf("/*                        3.学生排名信息                      */\n                  ");
	printf("/*                                                            */\n                  ");
	printf("/*                        4.修改密码                          */\n                  ");
	printf("/*                                                            */\n                  ");
	printf("/*                        0.退出                              */\n                  ");
	printf("/*                                                            */\n                  ");
	printf("/*============================================================*/\n                  ");
	printf("请输入要选择的功能(0-3):");
}

//打印修改学生信息菜单(学生修改)
void print_modify_stu()
{
	printf("\n\n                  ");
	printf("/*=================修改学生信息=================*/\n                  ");
	printf("/*                 1.修改姓名                   */\n                  ");
	printf("/*                 2.修改性别                   */\n                  ");
	printf("/*                 3.修改年龄                   */\n                  ");
	printf("/*                 4.修改出生日期               */\n                  ");
	printf("/*                 5.修改联系方式               */\n                  ");
	printf("/*                 6.修改家庭地址               */\n                  ");
	printf("/*                 0.退出                       */\n                  ");
	printf("/*==============================================*/\n                  ");
	printf("请输入要选择的功能(0-6):");

}

//学生修改自己信息
void modify_stu(char id[])
{
	student *head, *stu;
	char ch;
	head = read_stu();
	for (stu = head->next; stu != NULL; stu = stu->next)
		if (strcmp(stu->id, id) == 0)
			break;
	while (1)
	{
		system("cls");
		print_modify_stu(id);
		do
		{
			ch = getch();
		} while (ch < 48 || ch>54);
		printf("%c", ch);
		switch (ch)
		{
		case 49:
			printf("\n                  原姓名:%s", stu->name);
			printf("\n                  请输新姓名:");
			scanf("%s", stu->name);
			break;
		case 50:
			printf("\n                  原性别:%s", stu->sex);
			printf("\n                  请输入新性别:");
			scanf("%s", stu->sex);
			break;
		case 51:
			printf("\n                  原年龄:%d", stu->age);
			printf("\n                  请输入新年龄:");
			scanf("%d", &stu->age);
			break;
		case 52:
			printf("\n                  原出生日期:%d.%d.%d", stu->birthday.year, stu->birthday.month, stu->birthday.day);
			printf("\n                  请输入新出生日期:");
			scanf("%d.%d.%d", &stu->birthday.year, &stu->birthday.month, &stu->birthday.day);
			while (!(0 < stu->birthday.year && 0 < stu->birthday.month&&stu->birthday.month <= 12 && 0 < stu->birthday.day&&stu->birthday.day <= 31))
			{
				printf("\n                  请输入正确的日期:");
				scanf("%d.%d.%d", &stu->birthday.year, &stu->birthday.month, &stu->birthday.day);
			}
			break;
		case 53:
			printf("\n                  原联系方式:%s", stu->phone);
			printf("\n                  请输入新联系方式:");
			scanf("%s", stu->phone);
			while (strlen(stu->phone) != 11)
			{
				printf("\n                  请输入正确的手机号码:");
				scanf("%s", stu->phone);
			}
			break;
		case 54:
			printf("                  原地址:%s", stu->addr);
			printf("\n                  请输入新家庭地址:");
			scanf("%s", stu->addr);
			break;
		case 48:
			return;
			break;
		default:
			break;
		}
		printf("\n                  修改成功,按任意键继续!");
		save_stu(head);
		getch();
	}
}

//对学生登录界面进行操作
void select_stu_menu(char id[])
{
	char ch;
	while (1)
	{
		system("cls");
		print_stu_menu(id);
		do
		{
			ch = getch();
		} while (ch<48 || ch>52);
		system("cls");
		switch (ch)
		{
		case 49:     search_stu(id);
			break;
		case 50:    modify_stu(id);
			break;
		case 51:    select_grade_stu(id);
			break;
		case 52:    key(id);
				return;
			break;
		case 48: return;
			break;
		default:
			break;
		}
	}
}

//学生登录
void stu_login()
{
	vistor *head, *temp;
	int i, flag;
	char ch, choice;
	char id[20], passward[13];
	head = read_vistor();
	do
	{
		system("cls");
		printf("\n\n                                      学生登录");
		do {
			printf("\n\n                                账号(8位):");
			scanf("%s", id);
		} while (strlen(id) !=8 );
		printf("\n                                密码:");
		for (i = 0; i < 12; i++)
		{
			do {
				ch = getch();								
			} while (legal_pass(ch)!=1);
			if (i == 0 && (ch == '\r'||ch=='\b'))
			{
				i--;
			}
			else if (i > 0 && ch == '\r')
			{
				break;
			}
			else if (i > 0 && ch == '\b')
			{
				printf("\b \b");
				passward[i] = '\0';
				i -= 2;
			}
			else
			{
				printf("*");
				passward[i] = ch;
			}
		}
		passward[i] = '\0';
		flag = 0;
		for (temp = head->next; temp != NULL; temp = temp->next)
		{
			if (strcmp(temp->id, id) == 0 && strcmp(temp->passward, passward) == 0)
			{
				flag = 1;
				break;
			}
		}
		if (flag == 0)
		{
			printf("\n                                用户名不存在或密码错误!");
			printf("\n                                是否重新登录?(Y/N)");
			do
			{
				choice = getch();
			} while (choice != 'y' && choice != 'Y' && choice != 'N' && choice != 'n');
			if (choice == 'n' || choice == 'N')
				return;
		}
	} while ((choice == 'Y' || choice == 'y') && flag == 0);
	if (flag == 1)
	{
		printf("\n                                正在登录");
		for (i = 0; i < 7; i++)
		{
			printf(".");
			Sleep(200);
		}
		printf("\n                                登录成功!");
		getch();
		select_stu_menu(id);
	}
}

//查看学生排名(学生查看,自己的信息为红色)
void select_grade_stu(char id[])
{
	student *head, *stu;
	HANDLE fontcolor;
	int i;
	char ch;
	fontcolor = GetStdHandle(STD_OUTPUT_HANDLE);
	head = read_stu();
	while(1)
	{
		i = 0;
		system("cls");
		print_grade_menu();
		do
		{
			ch = getch();
		} while (ch<48 || ch>52);
		switch (ch)
		{
		case 49:
			printf("\n\n                  排名    学号     姓名     高数\n");
			grade_math_sort(head);
			for (stu = head->next; stu != NULL; stu = stu->next)
			{
				if (strcmp(id, stu->id) == 0)
				{
					SetConsoleTextAttribute(fontcolor,FOREGROUND_RED);
					printf("                  NO.%-3d%-11s%-10s%c\n", ++i, stu->id, stu->name, stu->grade.math);
					SetConsoleTextAttribute(fontcolor, FOREGROUND_RED |FOREGROUND_GREEN |FOREGROUND_BLUE);
					continue;
				}
				printf("                  NO.%-3d%-11s%-10s%c\n", ++i, stu->id, stu->name, stu->grade.math);
			}
			break;
		case 50:
			printf("\n\n                  排名    学号     姓名     C语言\n");
			grade_c_sort(head);
			for (stu = head->next; stu != NULL; stu = stu->next)
			{
				if (strcmp(id, stu->id) == 0)
				{
					SetConsoleTextAttribute(fontcolor, FOREGROUND_RED);
					printf("                  NO.%-3d%-11s%-11s%c\n", ++i, stu->id, stu->name, stu->grade.c_language);
					SetConsoleTextAttribute(fontcolor, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
					continue;
				}
				printf("                  NO.%-3d%-11s%-11s%c\n", ++i, stu->id, stu->name, stu->grade.c_language);
			}
			break;
		case 51:
			printf("\n\n                  排名    学号     姓名     英语\n");
			grade_english_sort(head);
			for (stu = head->next; stu != NULL; stu = stu->next)
			{
				if (strcmp(id, stu->id) == 0)
				{
					SetConsoleTextAttribute(fontcolor, FOREGROUND_RED);
					printf("                  NO.%-3d%-11s%-10s%c\n", ++i, stu->id, stu->name, stu->grade.english);
					SetConsoleTextAttribute(fontcolor, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
					continue;
				}
				printf("                  NO.%-3d%-11s%-10s%c\n", ++i, stu->id, stu->name, stu->grade.english);
			}
			break;
		case 52:
			printf("\n\n                  排名    学号     姓名     总评\n");
			score_sort(head);
			for (stu = head->next; stu != NULL; stu = stu->next)
			{
				if (strcmp(id, stu->id) == 0)
				{
					SetConsoleTextAttribute(fontcolor, FOREGROUND_RED);
					printf("                  NO.%-3d%-11s%-10s%c\n", ++i, stu->id, stu->name, stu->grade.all);
					SetConsoleTextAttribute(fontcolor, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
					continue;
				}
				printf("                  NO.%-3d%-11s%-10s%c\n", ++i, stu->id, stu->name, stu->grade.all);
			}
			break;
		case 48:
			return;
			break;
		default:
			break;
		}
		printf("\n按任意键继续!");
		getch();		
	} 
}

/*******************************************
文件名:file.c
功  能:与管理员操作有关的函数。
********************************************/

//管理员登录菜单
void print_user_menu()
{
	system("cls");
	printf("\n\n                  ");
	printf("/*=====================欢迎管理学生信息!=====================*/\n                  ");
	printf("/*                                                            */\n                  ");
	printf("/*                       1.录入学生信息                       */\n                  ");
	printf("/*                                                            */\n                  ");
	printf("/*                       2.修改学生信息                       */\n                  ");
	printf("/*                                                            */\n                  ");
	printf("/*                       3.删除学生信息                       */\n                  ");
	printf("/*                                                            */\n                  ");
	printf("/*                       4.浏览学生信息                       */\n                  ");
	printf("/*                                                            */\n                  ");
	printf("/*                       5.查询学生信息                       */\n                  ");
	printf("/*                                                            */\n                  ");
	printf("/*                       6.学生排名信息                       */\n                  ");
	printf("/*                                                            */\n                  ");
	printf("/*                       0.退出                               */\n                  ");
	printf("/*                                                            */\n                  ");
	printf("/*============================================================*/\n                  ");
	printf("请输入要选择的功能(0-6):");
}

//对学生信息进行管理
void select_user_menu()
{
	char ch;

	while (1)
	{
		print_user_menu();
		do
		{
			ch = getch();
		} while (ch<48 || ch>54);
		system("cls");
		switch (ch)
		{
		case 49:    create_stu();
			break;
		case 50:    select_modify();
			break;
		case 51:    select_del();
			break;
		case 52:    select_watch();
			break;
		case 53:    select_search();
			break;
		case 54:    select_grade();
			break;
		case 48: return;
			break;
		default:
			break;
		}
	}
}

//打印修改学生信息方式菜单(按学号查找修改、按姓名查找修改)
void print_modify_menu()
{
	printf("\n\n                  ");
	printf("/*=================修改学生信息=================*/\n                  ");
	printf("/*                                              */\n                  ");
	printf("/*                 1.按姓名修改                 */\n                  ");
	printf("/*                                              */\n                  ");
	printf("/*                 2.按学号修改                 */\n                  ");
	printf("/*                                              */\n                  ");
	printf("/*                 0.返回主菜单                 */\n                  ");
	printf("/*                                              */\n                  ");
	printf("/*==============================================*/\n                  ");
	printf("请输入要选择的功能(0-2):");
}

//选择修改学生信息的方式(按学号查找修改、按姓名查找修改)
void select_modify()
{
	student *head, *stu;
	char name[20], id[10];
	char ch;
	int  flag;
	head = read_stu();
	if (head->next == NULL)
	{
		printf("\n\n                  暂未存储学生信息,按任意键返回主菜单!\n");
		getch();
		return;
	}
	while (1)
	{
		flag = 0;
		system("cls");
		print_modify_menu();
		do
		{
			ch = getch();
		} while (ch < 48 || ch>50);
		switch (ch)
		{
		case 49:
			printf("\n                  请输入要修改学生的姓名:");
			scanf("%s", name);
			for (stu = head->next; stu != NULL; stu = stu->next)
				if (strcmp(stu->name, name) == 0)
				{
					modify(stu);
					flag = 1;
					break;
				}
			break;
		case 50:
			printf("\n                  请输入要修改学生的学号:");
			scanf("%s", id);
			for (stu = head->next; stu != NULL; stu = stu->next)
				if (strcmp(stu->id, id) == 0)
				{
					modify(stu);
					flag = 1;
					break;
				}
			break;
		case 48:
			return;
			break;
		default:
			flag = 0;
			break;
		}
		if (flag == 0)
		{
			printf("\n                  未找到该学生,按任意键继续!");
			getch();
		}
	}
}

//打印修改学生信息菜单
void modify_choices()
{
	printf("\n\n                  ");
	printf("/*=================修改学生信息=================*/\n                  ");
	printf("/*                 1.修改学号                   */\n                  ");
	printf("/*                 2.修改姓名                   */\n                  ");
	printf("/*                 3.修改性别                   */\n                  ");
	printf("/*                 4.修改年龄                   */\n                  ");
	printf("/*                 5.修改出生日期               */\n                  ");
	printf("/*                 6.修改成绩                   */\n                  ");
	printf("/*                 7.修改联系方式               */\n                  ");
	printf("/*                 8.修改家庭地址               */\n                  ");
	printf("/*                 0.退出                       */\n                  ");
	printf("/*==============================================*/\n                  ");
	printf("请输入要选择的功能(0-8):");

}

//修改学生信息(管理员修改,可修改学生学)
void modify(student *stu)
{
	student *head, *head1,*stu1,*stu2;
	vistor *v_head, *vis;
	char ch,choice;
	int flag = 1;
	head = read_stu();
	v_head = read_vistor();
	for (stu1 = head->next; stu1 != NULL; stu1 = stu1->next)
		if (strcmp(stu1->id, stu->id) == 0)
			break;
	for (vis = v_head->next; vis != NULL; vis = vis->next)
		if (strcmp(vis->id, stu->id) == 0)
			break;
	while (1)
	{
		head1 = read_stu();
		system("cls");
		modify_choices();
		do
		{
			ch = getch();
		} while (ch < 48 || ch>56);
		switch (ch)
		{
		case 49:
			printf("\n                  原学号为:%s\n", stu1->id);
			printf("\n                  请输入新学号:");
			while (flag == 1 || strlen(stu1->id) != 8)
			{
				scanf("%s", stu1->id);
				flag = 0;
				if (strlen(stu1->id) != 8)
				{
					printf("\n                  请输入8位学号:");
					scanf("%s", stu1->id);
				}
				for (stu2 = head1->next; stu2 != NULL; stu2 = stu2->next)
					if (strcmp(stu2->id, stu1->id) == 0)
					{
						flag = 1;
						printf("                  此学号已存在,请重新录入!\n");
						printf("\n                  请重新输入学号:");
						break;
					}
			}
			flag = 1;
			strcpy(vis->id, stu1->id);
			strcpy(vis->passward, stu1->id);
			break;
		case 50:
			printf("\n                  原姓名为:%s\n", stu1->name);
			printf("\n                  请输入新姓名:");
			scanf("%s", stu1->name);
			break;
		case 51:
			printf("\n                  原性别为:%s\n", stu1->sex);
			printf("\n                  请输入新性别:");
			scanf("%s", stu1->sex);
			break;
		case 52:
			printf("\n                  原年龄为:%d\n", stu1->age);
			printf("\n                  请输入新年龄:");
			scanf("%d", &stu1->age);
			break;
		case 53:
			printf("\n                  原出生日期为:%d.%d.%d", stu1->birthday.year, stu1->birthday.month, stu1->birthday.day);
			printf("\n                  请输入新出生日期(例xxxx.xx.xx):");
			scanf("%d.%d.%d", &stu1->birthday.year, &stu1->birthday.month, &stu1->birthday.day);
			while (!(0 < stu1->birthday.year && 0 < stu1->birthday.month&&stu1->birthday.month <= 12 && 0 < stu1->birthday.day&&stu1->birthday.day <= 31))
			{
				printf("\n                  请输入正确的日期:");
				scanf("%d.%d.%d", &stu1->birthday.year, &stu1->birthday.month, &stu1->birthday.day);
			}
			break;
		case 54:
			printf("\n                  请输入新成绩:");
			printf("\n                  原高数成绩为:%f\n", stu1->score.math);
			printf("                  请输入新高数成绩(0-100):");
			scanf("%f", &stu1->score.math);
			while (!(0 <= stu1->score.math&& stu1->score.math <= 100))
			{
				printf("\n                  请输入正确的成绩:");
				scanf("%f", &stu1->score.math);
			}
			printf("\n                  原C语言成绩为:%f\n", stu1->score.c_language);
			printf("                  请输入新C语言成绩(0-100):");
			scanf("%f", &stu1->score.c_language);
			while (!(0 <= stu1->score.c_language && stu1->score.c_language <= 100))
			{
				printf("\n                  请输入正确的成绩:");
				scanf("%f", &stu1->score.c_language);
			}
			printf("\n                  原英语成绩为:%f\n", stu1->score.english);
			printf("                  请输入新英语成绩(0-100):");
			scanf("%f", &stu1->score.english);
			while (!(0 <= stu1->score.english && stu1->score.english <= 100))
			{
				printf("\n                  请输入正确的成绩:");
				scanf("%f", &stu1->score.english);
			}
			stu1->score.all = stu1->score.math + stu1->score.c_language + stu1->score.english;
			stu1->score.ave = stu1->score.all / 3;
			stu1->grade.math = grade_assess(stu1->score.math);
			stu1->grade.c_language = grade_assess(stu1->score.c_language);
			stu1->grade.english = grade_assess(stu1->score.english);
			stu1->grade.all = grade_assess(stu1->score.ave);
			break;
		case 55:
			printf("\n                  原联系方式为:%s\n", stu1->phone);
			printf("\n                  请输入新联系方式:");
			scanf("%s", stu1->phone);
			while (strlen(stu1->phone) != 11)
			{
				printf("\n                  请输入正确的手机号码:");
				scanf("%s", stu1->phone);
			}
			break;
		case 56:
			printf("\n                  原家庭地址为:%s\n", stu1->addr);
			printf("\n                  请输入新家庭地址:");
			scanf("%s", stu1->addr);
			break;
		case 48:
			return;
			break;
		default:
			break;
		}
		printf("                  是否保存修改信息?(Y/N)");
		do
		{
			choice = getch();
		} while (choice != 'y' && choice != 'Y' && choice != 'N' && choice != 'n');
		if (choice == 'y' || choice == 'Y')
		{
			save_stu(head);
			save_vistor(v_head);
			printf("\n                  保存成功,按任意键继续!");
		}
		else
			printf("\n                  未保存修改,按任意键继续!");
		getch();
	}
}

//打印删除菜单
void print_del_menu()
{
	printf("\n\n                  ");
	printf("/*=================删除学生信息=================*/\n                  ");
	printf("/*                                              */\n                  ");
	printf("/*                 1.按姓名删除                 */\n                  ");
	printf("/*                                              */\n                  ");
	printf("/*                 2.按学号删除                 */\n                  ");
	printf("/*                                              */\n                  ");
	printf("/*                 0.返回主菜单                 */\n                  ");
	printf("/*                                              */\n                  ");
	printf("/*==============================================*/\n                  ");
	printf("请输入要选择的功能(0-2):");
}

//删除学生信息(学生信息删除,学生账号、密码也会被删除)
void select_del()
{
	student *head, *pre, *temp;
	vistor *v_head, *v_pre, *v_temp;
	char name[40], id[10];
	char choice;
	int  count;
	char ch;
	while(1)
	{
		head = read_stu();
		if (head->next == NULL)
		{
			printf("\n\n                  暂未存储学生信息,按任意键返回主菜单!\n");
			getch();
			return;
		}
		pre = head;
		v_head = read_vistor();
		v_pre = v_head;
		count = 0;
		system("cls");
		print_del_menu();
		do
		{
			ch = getch();
		} while (ch<48 || ch>50);
		switch (ch)
		{
		case 49:
			printf("\n                  请输入要删除学生的姓名:");
			scanf("%s", name);
			for (temp = pre->next; temp != NULL; temp = temp->next)
			{
				if (strcmp(temp->name, name) == 0)
				{
					count = 1;
					printf("\n                  该学生信息如下:");
					print_stu(temp);
					printf("                  是否删除?(Y/N)");
					choice = getch();
					if (choice == 'y' || choice == 'Y')
					{
						for (v_temp = v_pre->next; v_temp != NULL; v_temp = v_temp->next)
						{
							if (strcmp(v_temp->id, temp->id))
							{
								v_pre->next = v_temp->next;
								free(v_temp);
								break;
							}
						}
						pre->next = temp->next;
						free(temp);
						save_stu(head);
						save_vistor(v_head);
						printf("                  该学生信息已删除!\n");
						break;
					}
					else 
					{
						printf("                  已放弃删除该学生信息!\n");
						break;
					}
				}
				pre = pre->next;
			}
			break;
		case 50:
			printf("\n                  请输入要删除学生的学号:");
			scanf("%s", id);
			for (temp = pre->next; temp != NULL; temp = temp->next)
			{
				if (strcmp(temp->id, id) == 0)
				{
					count = 1;
					printf("\n                  该学生信息如下:");
					print_stu(temp);
					printf("\n                  是否删除?(Y/N)\n");
					choice = getch();
					if (choice == 'y' || choice == 'Y')
					{
						for (v_temp = v_pre->next; v_temp != NULL; v_temp = v_temp->next)
						{
							if (strcmp(v_temp->id, temp->id))
							{
								v_pre->next = v_temp->next;
								free(v_temp);
								break;
							}
						}
						pre->next = temp->next;
						free(temp);
						save_stu(head);
						save_vistor(v_head);
						printf("\n                  该学生信息已删除!\n");
						break;
					}
					else
					{
						printf("\n                  已放弃删除该学生信息!\n");
						break;
					}
				}
				pre = pre->next;
			}
			break;
		case 48:
			return;
			break;
		default:
			break;
		}
		if (count == 0)
			printf("                  未找到该学生信息!");
		printf("\n                  按任意键继续!");
		getch();
	}
}

//打印查找学生信息菜单
void print_search_menu()
{
	printf("\n\n                  ");
	printf("/*=================查找学生信息=================*/\n                  ");
	printf("/*                                              */\n                  ");
	printf("/*                  1.按姓名查找                */\n                  ");
	printf("/*                                              */\n                  ");
	printf("/*                  2.按学号查找                */\n                  ");
	printf("/*                                              */\n                  ");
	printf("/*                  0.返回主菜单                */\n                  ");
	printf("/*                                              */\n                  ");
	printf("/*==============================================*/\n                  ");
	printf("请输入要选择的功能(0-2):");
}

//查找学生信息
void select_search()
{
	student *head, *stu;
	char name[40], id[10];			//查询的姓名、学号
	int count;
	char ch;
	head = read_stu();
	if (head->next == NULL)
	{
		printf("\n\n                  暂未存储学生信息,按任意键返回主菜单!\n");
		getch();
		return;
	}
	while(1)
	{
		count = 0;
		system("cls");
		print_search_menu();
		do
		{
			ch = getch();
		} while (ch<48 || ch>50);
		printf("%c", ch);
		switch (ch)
		{
		case 49:
			printf("\n                  请输入要查找学生的姓名:");
			scanf("%s", name);
			for (stu = head->next; stu != NULL; stu = stu->next)
				if (strcmp(stu->name, name) == 0)
				{
					count = 1;
					break;
				}
			break;
		case 50:
			printf("\n                  请输入要查找学生的学号:");
			scanf("%s", id);
			for (stu = head->next; stu != NULL; stu = stu->next)
				if (strcmp(stu->id, id) == 0)
				{
					count = 1;
					break;
				}
			break;
		case 48:
			return;
			break;
		default:
			break;
		}
		if (count == 0)
			printf("                  未找到该学生信息!\n");
		else
		{
			printf("                  该学生信息如下:\n");
			print_stu(stu);
		}
		printf("\n                  按任意键继续!");
		getch();
	}

}

//打印浏览学生信息菜单(可查看学生账号密码)
void print_watch_menu()
{
	system("cls");
	printf("\n\n                  ");
	printf("/*======================浏览学生信息======================*/\n                  ");
	printf("/*                                                        */\n                  ");
	printf("/*                      1.浏览成绩信息                    */\n                  ");
	printf("/*                                                        */\n                  ");
	printf("/*                      2.浏览户籍信息                    */\n                  ");
	printf("/*                                                        */\n                  ");
	printf("/*                      3.查看学生密码                    */\n                  ");
	printf("/*                                                        */\n                  ");
	printf("/*                      0.返回主菜单                      */\n                  ");
	printf("/*                                                        */\n                  ");
	printf("/*========================================================*/\n                  ");
	printf("请输入要选择的功能(0-3):");
}

//浏览学生信息
void select_watch()
{
	char ch;
	student *head,*stu;
	head = read_stu();
	system("cls");
	if (head->next == NULL)
	{
		printf("\n\n                  暂未存储学生信息,按任意键返回主菜单!\n");
		getch();
		return;
	}
	while(1)
	{
		print_watch_menu();
		do
		{
			ch = getch();
		} while (ch<48 || ch>51);
		printf("\n\n                  该班数据为:\n");
		switch (ch)
		{
		case 49:
			score_sort(head);
			printf("                    学号    姓名      高数     C语言    英语   平均成绩  总成绩 \n");
			for (stu = head->next; stu != NULL; stu = stu->next)
				printf("                  %-10s%-10s%-9.1f%-9.1f%-9.1f%-9.1f%-9.1f\n", stu->id, stu->name, stu->score.math, stu->score.english, stu->score.c_language, stu->score.ave, stu->score.all);
			break;
		case 50:
			id_sort(head);
			printf("                    学号    姓名     性别 年龄   出生日期    联系方式      家庭地址\n");
			for (stu = head->next; stu != NULL; stu = stu->next)
				printf("                  %-10s%-10s%-5s%-5d%4d.%2d.%-4d%-13s%s\n", stu->id, stu->name, stu->sex, stu->age, stu->birthday.year, stu->birthday.month, stu->birthday.day, stu->phone, stu->addr);
			break;
		case 51:
			print_vis();
			break;
		case 48:
			return;
			break;
		default:
			break;
		}
		printf("\n                  按任意键继续!");
		getch();
	}
}

//查看学生排名(可查看各科成绩排名)
void select_grade()
{
	student *head, *stu;
	int i;
	char ch;
	head = read_stu();
	if (head->next == NULL)
	{
		printf("\n\n                  暂未存储学生信息,按任意键返回主菜单!\n");
		getch();
		return;
	}
	while(1)
	{
		i = 0;
		system("cls");
		print_grade_menu();
		do
		{
			ch = getch();
		} while (ch<48 || ch>52);
		switch (ch)
		{
		case 49:
			printf("\n\n                  排名    学号     姓名     高数\n");
			grade_math_sort(head);
			for (stu = head->next; stu != NULL; stu = stu->next)
				printf("                  NO.%-3d%-11s%-10s%c\n", ++i, stu->id, stu->name, stu->grade.math);
			break;
		case 50:
			printf("\n\n                  排名    学号     姓名     C语言\n");
			grade_c_sort(head);
			for (stu = head->next; stu != NULL; stu = stu->next)
				printf("                  NO.%-3d%-11s%-11s%c\n", ++i, stu->id, stu->name, stu->grade.c_language);
			break;
		case 51:
			printf("\n\n                  排名    学号     姓名     英语\n");
			grade_english_sort(head);
			for (stu = head->next; stu != NULL; stu = stu->next)
				printf("                  NO.%-3d%-11s%-10s%c\n", ++i, stu->id, stu->name, stu->grade.english);
			break;
		case 52:
			printf("\n\n                  排名    学号     姓名     总评\n");
			score_sort(head);
			for (stu = head->next; stu != NULL; stu = stu->next)
				printf("                  NO.%-3d%-11s%-10s%c\n", ++i, stu->id, stu->name, stu->grade.all);
			break;
		case 48:
			return;
			break;
		default:
			break;
		}
		printf("\n                  按任意键继续!");
		getch();
	} 
}

你可能感兴趣的:(C++,链表)