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. 登录界面
    在这里插入图片描述
  2. 管理员界面
    在这里插入图片描述
  3. 学生登录界面
    在这里插入图片描述

详细设计

  1. 管理员注册:注册管理员账号与密码(输入过程中可删除)。管理员的账号由字母、数字和下划线组成,不合法的用户名无法注册成功。
    在这里插入图片描述

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

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

在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述
6. 浏览学生信息:可浏览的学生的的成绩信息(按成绩排序)、户籍信息(按学号排序)以及现有学生账号与密码,每进入某一模块会重新排序,学生账号保存于另一文件,不进行排序。
在这里插入图片描述
7. 查找学生信息:可按姓名或学号查找学生信息,显示学生全部信息。
在这里插入图片描述

  1. 学生排名信息:按成绩给学生A、B、C、D四个评价,可查看高数、C语言、英语、总成绩等排名,各个模块按成绩排序,成绩相同按学号排序。当学生登陆查看时,自己的信息会变红色。
    在这里插入图片描述
  2. 修改密码:修改学生密码。当三次输错原密码,将会退出学生登录,须重新登录方可进行操作,当修改成功后也会退出登录,须重新登录。
    在这里插入图片描述

测试数据及运行结果

  1. 管理员注册
    在这里插入图片描述
  2. 管理员登录
    在这里插入图片描述
  3. 数据录入
    在这里插入图片描述
  4. 数据修改
    在这里插入图片描述
    在这里插入图片描述
  5. 数据删除
    在这里插入图片描述
  6. 数据查询
    在这里插入图片描述
  7. 数据浏览

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
8. 学生登录(菜单会显示学生学号)
在这里插入图片描述
9. 学生排名信息(按各科成绩排序,不显示分数,只显示分数对应的评价)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
10. 修改密码
在这里插入图片描述
在这里插入图片描述

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

调试情况:
在最开始,从文件读取数据时只有成功时才返回一个链表的头节点,导致当未录入数据时,或未建立存储信息的文本文件时,总是显示读出有错,之后我让未建立文本文件或未存储学生信息时也返回链表的头指针,不过头结点的指针域指向空。这样可以通过判断指针域的情况判断文件是否有数据。
在用户登录时,用来存储用户名的字符数组大小是固定的,管理员为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 <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <Windows.h>


/********************************结构体**********************************/
//学生成绩结构体
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();
	} 
}
  • 18
    点赞
  • 130
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值