学生学分信息管理系统-C语言

学生学分信息管理系统-C语言

程序设计要求

管理员:
1.对学生已修学分信息进行管理
2.对学生密码进行查看和修改
3.查询:按学号查询某学生的情况;按班级号查询所有同学;按某种课程,输出未达标要求的学生名单。

学生:
1.查询自己信息,学分
2.对自己的密码进行修改

运用函数,链表,指针及相关知识完成。

程序运行介绍

1、程序运行
在程序开始运行时,系统自动从后台读取上次已经保存的数据文件,并自动保存在链表中。
2、系统切换
通过用户在登陆界面选择不同的登录方式,根据选择输入个人密码,从而进入不同的菜单(管理员菜单与学生菜单)。特别的,本系统实现了三次密码输入错误自动退出的功能。
3、管理员系统
进入管理员系统,用户可以通过输入对应的数字进入对应功能,包括:
(1)对学生信息的录入、修改、查询、删除
(2)按课程号输出未达标的学生
(3)浏览、统计学生信息
4、学生系统
(1) 查询信息
(2) 修改密码
学生学分信息管理系统-C语言_第1张图片

数据及数据结构设计描述

本系统定义的链表为学生链表:
其成员有:学生姓名,学生密码,学号,班级号,五类课程学分和总学分

详细设计

4.1 void stupassword
函数功能:确认管理员身份。读取文件,显示登录界面,通过if函数进入不同的密码输入界面;此外若三次密码输入错误,则退出系统。
4.2 void inputstu
函数功能:输入一个学生的信息 ,将学生信息加入已有链表。
4.3 void outputstu
函数功能:打印学生信息,输出链表中学生信息结点的数据。(包括学生姓名,学生密码,学号,班级号,五类课程学分和总学分)
4.4 void deletenode
函数功能:按学号查找并删除学生信息创建新链表,对学生信息进行遍历,找到并进行删除。
4.5 void searchnode1
函数功能:按照学号、班级号查找信息。
4.6 void searchnode2
按班级号查找(按学号大小显示一个班级的情况),输出为整个班级的学生信息。
4.7 void searchnode 3、4
函数功能:输入课程号,按班级号查找(按姓名拼音顺序输出学生信息)。
4.8 void revise
函数功能:按学号查找并修改学生信息
4.9 void allqualifiedstu
函数功能:打印所有可以毕业的学生信息,对所有学生信息进行遍历,判断总学分是否达到要求的200分,并将可以毕业的学生信息打印出来
4.10 void stustatistic
函数功能:按课程号输出未达标的学生。
4.11 void stusave
函数功能:保存文件。
4.12 void stupassword
函数功能: 管理员或学生对密码进行修改。
4.13 void printlist
函数功能:打印链表,输出学生信息。
4.14 void inputg
函数功能:用头插法插入产品信息,若出现重复输入,则返回并重新输入。
4.15 void stupasswordrevise
函数功能:学生修改自己的密码;
追加功能:密码需要两次确认方可修改成功,此目的是防止学生修改密码时误录入错误密码,只需要调用strcmp函数对密码1和密码2进行比较即可。
4.16 void stuview
函数功能:令学生查看信息。
4.17 void keydown1
函数功能:令学生选择操作。
4.18 void readfile
函数功能:从文件中读取信息。
4.19 void writefile
函数功能:从链表中读取文件,写进文本.txt里。

学生菜单:
学生学分信息管理系统-C语言_第2张图片
管理员菜单
学生学分信息管理系统-C语言_第3张图片

代码实现(Visual Studio)

#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include


struct student
{
	char name[20];
	char password[20];//学生密码(学生可以修改)
	int num;//学号
	int classnum;//班级号
	int credit[5], allcredit;//五类课程学分和总学分
	struct student* next;
};

//管理员操作
void menu1();//学生菜单
void menu2();//管理员菜单
void keydown1(int num);//学生选择操作
void keydown2(struct student* list);//管理员选择操作
int Confirm1(int num);//确认学生身份
int Confirm2();//确认管理员身份
void inputstu(struct student* stu); //输入一个学生的信息
void outputstu(struct student* stu); //输出一个学生的信息
struct student* createlist();//创建链表
void insertnode(struct student* headnode, struct student* data);//插入节点(头插法)
void deletenode(struct student* headnode, int num);//按学号查找并删除节点
void searchnode1(struct student* headnode, int num);//按学号查找结点
void searchnode2(struct student* headnode, int classnum);//按班级号查找(按学号大小显示一个班级的情况)
void searchnode3(struct student* headnode, int classnum);//按班级号查找(按姓名拼音顺序输出学生信息)
void searchnode4(struct student* headnode, int subnum);//输入课程号,输出未达标学生信息
void revise(struct student* headnode, int num);//按学号查找并修改学生信息0
void allqualifiedstu(struct student* headnode);//打印所有可以毕业的学生信息
void printlist(struct student* headnode);//打印链表
void readfile(char* filename);//从文件中读取信息
void writefile(struct student* headnode, char* filename);//从链表中读取文件,写进文本1.txt里
void save(char* filename);//将信息保存到最终的文件stu.txt里

void stustatistic(struct student* headnode);//统计功能(输入学号,输出该学生的课程总学分;输入班级号,输出达标人数和没有达标的学生人数及其信息)
void stupasswordmanage(struct student* headnode);//查看学生密码


//学生操作
void stuview(int num);//学生查看信息
void stupasswordrevise(int num);//学生修改密码



int main()
{
	int c,num;
	struct student* list = createlist();
	struct student* stu = (struct student*)malloc(sizeof(struct student));
	printf("请问您是学生还是管理员:\n");
	printf("1.学生   2.管理员\n");
	scanf_s("%d", &c);
	if (c == 1)
	{
		printf("请输入您的学号:\n");
		scanf_s("%d", &num);
		if (Confirm1(num)==1) {//确认学生身份
			while (1) {
				menu1();
				keydown1(num);
				system("pause");//暂停程序,等待任意键继续操作
			}
		}
	}
	else if (c == 2) {
		if (Confirm2() == 1) {//管理员密码正确
			while (1) {
				menu2();
				keydown2(list);
				system("pause");//暂停程序,等待任意键继续操作
			}
		}
	}
	else {
		printf("选择错误,请重新输入!\n");
	}
	return 0;
}

int Confirm1(int num)//确认学生身份
{
	FILE* fp = fopen("stu.txt", "r");//以只读方式打开文件
	int n=0;
	struct student a;
	char key[100];
	printf("请输入您的密码:\n");
	scanf_s("%s", key , sizeof(key));
	if (fp == NULL)
	{
		printf("文件无法打开!\n");
		exit(1);//异常退出
	}
	else {//在文件中查找该学生
		while (!feof(fp))
		{
			fscanf(fp, "%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%s\n", &a.num, a.name, &a.classnum, &a.credit[0], &a.credit[1], &a.credit[2], &a.credit[3], &a.credit[4], &a.allcredit, a.password);
			if (a.num == num)
			{
				n = 1;
				if (strcmp(a.password, key) == 0) {
					printf("登陆成功!\n");
					return 1;
				}
				else {
					printf("密码错误,您还有两次机会!请重新输入:\n");
					scanf_s("%s", key, sizeof(key));
					if (strcmp(a.password, key) == 0) {
						printf("登陆成功!\n");
						return 1;
					}
					else {
						printf("密码错误,您还有一次机会!请重新输入:\n");
						scanf_s("%s", key, sizeof(key));
						if (strcmp(a.password, key) == 0) {
							printf("登陆成功!\n");
							return 1;
						}
						else {
							printf("对不起,您无权限操作!\n");
							return 0;
						}
					}
				}
			}
		}
		if (n == 0) {
			printf("对不起,此学生不存在!\n");
			return 0;
		}
	}
}
int Confirm2()//确认管理员身份
{
	char key[100] = { "okk" };
	char a[100];
	printf("请输入管理员密码:\n");
	scanf_s("%s", a, sizeof(a));
	if (strcmp(a, key) == 0) {
		return 1;
	}
	else {
		printf("密码错误,您还有两次机会!请重新输入:\n");
		scanf_s("%s", a, sizeof(a));
		if (strcmp(a, key) == 0) {
			return 1;
		}
		else {
			printf("密码错误,您还有一次机会!请重新输入:\n");
			scanf_s("%s", a, sizeof(a));
			if (strcmp(a, key) == 0) {
				return 1;
			}
			else {
				return 0;
			}
		}
	}
}
void inputstu(struct student* stu) //输入一个学生的信息
{
	int k = 0;
	scanf_s("%d", &stu->num);
	scanf_s("%s", stu->name, sizeof(stu->name));//scanf_s函数输入字符串的时候需要特别注意一下
	scanf_s("%d", &stu->classnum);
	for (int i = 0; i < 5; i++) {
		scanf_s("%d", &stu->credit[i]);
		k += stu->credit[i];
	}
	scanf_s("%s", stu->password, sizeof(stu->password));
	stu->allcredit = k;

}
void outputstu(struct student* stu) //输出一个学生的信息
{
	struct student* pmove = stu;
	printf("%d\t%s\t%d\t", pmove->num, pmove->name, pmove->classnum);//学号、姓名、班级号
	for (int i = 0; i < 5; i++) {
		printf("%d\t", pmove->credit[i]);
	}
	printf("%d\n", pmove->allcredit);
}
struct student* createlist()//创建链表
{
	struct student* headnode = (struct student*)malloc(sizeof(struct student));//结构体变量表示表头,动态内存申请 
	//headnode = NULL;//headnode没有做初始化,作为表头,所以下面打印的时候从next开始打印
	headnode->next = NULL;
	return headnode;
}
void insertnode(struct student* headnode, struct student* data)//插入节点(头插法)
{
	struct student* newnode = (struct student*)malloc(sizeof(struct student));
	newnode = data;
	newnode->next = headnode->next;
	headnode->next = newnode;
}
void deletenode(struct student* headnode, int num)//按学号查找并删除节点
{
	struct student* posnode = headnode->next;
	struct student* posfrontnode = headnode;
	if (posnode == NULL)
	{
		printf("数据为空,无法删除!\n");
		return;
	}
	while (posnode != NULL) {
		if (posnode->num == num) {
			posfrontnode->next = posnode->next;//找到了,开始删除
			free(posnode);
			return;
		}
		else {
			posfrontnode = posnode;
			posnode = posnode->next;
		}
	}
	printf("该同学不存在,无法删除!\n");
	return;
}
void searchnode1(struct student* headnode, int num)//按学号查找学生信息
{
	struct student* pmove = headnode->next;
	if (pmove == NULL) {
		printf("文件为空,无法查找!\n");
		return;
	}
	while (pmove != NULL) {
		if (pmove->num == num) {
			outputstu(pmove);
			return;
		}
		else
			pmove = pmove->next;
	}
	printf("查找不到该同学!\n");
	return;
}
void searchnode2(struct student* headnode, int classnum)//按班级号查找(按学号大小显示一个班级的情况)
{
	struct student* stu[100];//一个班级最多100人
	int i = 0, t = 0;
	struct student* pmove = headnode->next;
	struct student* pnew = (struct student*)malloc(sizeof(struct student));
	if (pmove == NULL) {
		printf("文件为空,无法查找!\n");
		return;
	}
	while (pmove) {
		if (pmove->classnum == classnum) {
			stu[i] = (struct student*)malloc(sizeof(struct student));
			stu[i] = pmove;
			i++;
		}
		pmove = pmove->next;
	}
	if (i == 0) {
		printf("不存在该班级!\n");
		return;
	}
	else {//如果班级号存在,对同学学号进行升序排序
		for (int k = 0; k < i - 1; k++) {
			for (int j = 0; j < i - 1 - k; j++) {
				if (stu[j]->num > stu[j + 1]->num) {
					pnew = stu[j];
					stu[j] = stu[j + 1];
					stu[j + 1] = pnew;
				}
			}
		}
		printf("学号\t姓名\t班级号\t基础类课程\t专业基础类课程\t专业类课程\t专业选修课程\t实践课程\t总学分\n");
		for (int k = 0; k < i; k++) {
			outputstu(stu[k]);
		}
	}
}
void searchnode3(struct student* headnode, int classnum)//按班级号查找(按姓名拼音顺序输出学生信息)
{
	struct student* stu[100];//一个班级最多100人
	int i = 0, t = 0;
	struct student* pmove = headnode->next;
	struct student* pnew;
	if (pmove == NULL) {
		printf("文件为空,无法查找!\n");
		return;
	}
	while (pmove != NULL) {
		if (pmove->classnum == classnum) {
			stu[i] = (struct student*)malloc(sizeof(struct student));
			stu[i] = pmove;
			i++;
		}
		pmove = pmove->next;
	}
	if (i == 0) {
		printf("不存在该班级同学!\n");
		return;
	}
	else {//如果班级号存在,对姓名拼音大小进行升序排序
		for (int k = 0; k < i - 1; k++) {
			for (int j = 0; j < i - 1 - k; j++) {
				if (strcmp(stu[j]->name, stu[j + 1]->name) > 0) {
					pnew = stu[j];
					stu[j] = stu[j + 1];
					stu[j + 1] = pnew;
				}
			}
		}
		printf("学号\t姓名\t班级号\t基础类课程\t专业基础类课程\t专业类课程\t专业选修课程\t实践课程\t总学分\n");
		for (int k = 0; k < i; k++) {
			outputstu(stu[k]);
		}
	}
}
void searchnode4(struct student* headnode, int subnum)//输入课程号,输出未达标学生信息
{
	struct student* pmove = headnode->next;
	switch (subnum)
	{
	case 0:while (pmove) {
		if (pmove->credit[0] < 50) {
			outputstu(pmove);
		}
		pmove = pmove->next;
	}
		  break;
	case 1:
		while (pmove) {
			if (pmove->credit[1] < 50) {
				outputstu(pmove);
			}
			pmove = pmove->next;
		}
		break;
	case 2:
		while (pmove) {
			if (pmove->credit[2] < 36) {
				outputstu(pmove);
			}
			pmove = pmove->next;
		}
		break;
	case 3:
		while (pmove) {
			if (pmove->credit[3] < 24) {
				outputstu(pmove);
			}
			pmove = pmove->next;
		}
		break;
	case 4:
		while (pmove) {
			if (pmove->credit[4] < 40) {
				outputstu(pmove);
			}
			pmove = pmove->next;
		}
		break;
	default:
		printf("该课程号不存在!\n");
		break;
	}
}
void revise(struct student* headnode, int num)//按学号查找并修改学生信息
{
	struct student* pmove = headnode->next;
	if (pmove == NULL) {
		printf("文件为空,无法修改!\n");
		return;
	}
	while (pmove != NULL) {
		if (pmove->num == num) {
			int allcredit = 0;
			printf("%d\t%s\t%d\t", pmove->num, pmove->name, pmove->classnum);//学号、姓名、班级号
			for (int i = 0; i < 5; i++) {
				printf("%d\t", pmove->credit[i]);
				allcredit += pmove->credit[i] / 5;
			}
			printf("\n");
			printf("请输入您要修改的信息:\n");
			inputstu(pmove);
			return;
		}
		else
			pmove = pmove->next;
	}
	printf("查找不到该同学,无法修改!\n");
	return;

}
void printlist(struct student* headnode)//打印链表
{
	struct student* pmove = headnode->next;
	if (pmove == NULL) {
		printf("文件为空!\n");
	}
	else {
		printf("学号\t姓名\t班级号\t基础类课程\t专业基础类课程\t专业类课程\t专业选修课程\t实践课程\t总学分\n");
		while (pmove) {
			outputstu(pmove);
			pmove = pmove->next;
		}
	}
}
void allqualifiedstu(struct student* headnode)//打印所有可以毕业的学生信息
{
	int k = 0;
	struct student* pmove = headnode->next;
	while (pmove) {
		if (pmove->allcredit == 200) {
			outputstu(pmove);
			k++;
		}
		pmove = pmove->next;
	}
	if (k == 0) {
		printf("暂时没有符合毕业条件的学生,您可以提醒他们修补学分喔!\n");
	}
}
void stustatistic(struct student* headnode)
{
	int num, k = 0;
	int i = 0, t = 0;
	int classnum;
	struct student* pnew;
	struct student* pmove;
	struct student* stu[100];//一个班级最多100人
	pmove = headnode->next;
	int n = 0;
	while (1)
	{
		printf(" 请选择:\n");
		printf(" 1.查找学生的课程总学分\n");
		printf(" 2.查找班级达标情况\n");
		printf(" 请输入您的选项:\n");
		scanf_s("%d", &n);
		if (n == 1 || n == 2)
		{
			break;
		}
		else
			printf("输入错误,请重新输入哦\n");
	}
	if (n == 1)
	{
		printf("请输入要查找学生的学号:\n");
		scanf_s("%d", &num);
		while (pmove->num != num && pmove->next != NULL)
		{
			headnode = pmove;
			pmove = pmove->next;
		}
		if (pmove->num == num)
		{
			printf("%d", pmove->allcredit);
		}
		else
			printf("未查找到该学生,请检查是否输入错误\n");
	}
	if (n == 2)
	{
		printf("请输入要查找的班级:\n");
		scanf_s("%d", &classnum);
		if (pmove == NULL) {
			printf("文件为空,无法查找!\n");
			return;
		}
		while (pmove != NULL) {
			if (pmove->classnum == classnum) {
				stu[i] = (struct student*)malloc(sizeof(struct student));
				stu[i] = pmove;
				i++;
			}
			pmove = pmove->next;
		}
		if (i == 0) {
			printf("不存在该班级同学!\n");
			return;
		}
		else {//如果班级号存在,对姓名拼音大小进行升序排序
			for (int k = 0; k < i - 1; k++) {
				for (int j = 0; j < i - 1 - k; j++) {
					if (strcmp(stu[j]->name, stu[j + 1]->name) > 0) {
						pnew = stu[j];
						stu[j] = stu[j + 1];
						stu[j + 1] = pnew;
					}
				}
			}
			for (int k = 0; k < i; k++) {
				if (stu[k]->allcredit >= 200)
				{
					t++;
					outputstu(stu[k]);
				}
			}
			printf("达标人数:%d\n", t);
			printf("未达标人数:%d\n", i - t);
			for (int k = 0; k < i; k++)
			{
				if (stu[k]->allcredit < 200)
				{
					outputstu(stu[k]);
				}
				else
					printf("未找到该班级,请检查是否输入错误\n");
			}
		}
	}

}


void stupasswordmanage(struct student* headnode)//管理员查看学生密码
{
	int num,n=0;
	struct student* pmove = headnode->next;
	printf("请输入您要查看的学生学号:\n");
	scanf_s("%d", &num);
	if (pmove == NULL) {
		printf("文件为空!\n");
		return;
	}
	while (pmove) {
		if (pmove->num == num) {
			printf("%s\n", pmove->password);
			n = 1;
			return;
		}
		pmove = pmove->next;
	}
	if (n == 0) {
		printf("此学号不存在!\n");
	}
}
void stupasswordrevise(int num)//学生修改自己的密码
{
	int n = 0;
	char key;
	struct student a;
	FILE* fp = fopen("stu.txt", "r");//以只读方式打开文件	
	FILE* fpw = fopen("2.txt", "w");//临时文件,每次都刷新2.txt里面的内容,然后把stu里面的信息复制到2.txt里面,最后把2.txt重命名为stu.txt
	char newpassword1[20];
	char newpassword2[20];


	if (fp == NULL)
	{
		printf("文件无法打开!\n");
		exit(1);//异常退出
	}
	else {//在文件中查找该学生
		while (!feof(fp))
		{
			fscanf(fp, "%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%s\n", &a.num, a.name, &a.classnum, &a.credit[0], &a.credit[1], &a.credit[2], &a.credit[3], &a.credit[4], &a.allcredit, a.password);
			if (a.num == num)
			{
				n = 1;
				printf("请输入您的新密码:\n");
				scanf_s("%s", newpassword1, 20);
				printf("再次输入你的密码\n");
				scanf_s("%s", newpassword2, 20);
				if (strcmp(newpassword1, newpassword2) == 0)
				{
					strcpy(a.password, newpassword1);
					fprintf(fpw, "%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%s\n", a.num, a.name, a.classnum, a.credit[0], a.credit[1], a.credit[2], a.credit[3], a.credit[4], a.allcredit, a.password);
					printf("修改成功!\n");
				}
				else {
					printf("两次输入密码不一致,请重新输入!\n");
				}
			}
			else {
				fprintf(fpw, "%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%s\n", a.num, a.name, a.classnum, a.credit[0], a.credit[1], a.credit[2], a.credit[3], a.credit[4], a.allcredit, a.password);
			}
		}
		if (n == 0) {
			printf("对不起,此学生不存在!\n");
		}
	}
	fclose(fp);
	fclose(fpw);
	system("del stu.txt");
	system("rename 2.txt stu.txt");//将文件2重命名为stu文件
}
void stuview(int num)//学生查看信息
{
	struct student a;
	int n = 0;
	FILE* fp;
	fp = fopen("stu.txt", "r");//以只读方式打开文件
	if (fp == NULL)
	{
		printf("文件无法打开!\n");
		exit(1);//异常退出
	}
	else {
		while (!feof(fp))
		{
			fscanf(fp, "%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%s\n", &a.num, a.name, &a.classnum, &a.credit[0], &a.credit[1], &a.credit[2], &a.credit[3], &a.credit[4], &a.allcredit, a.password);
			if (a.num == num)
			{
				n = 1;
				outputstu(&a);
				fclose(fp);
				return;
			}
		}
		if(n==0)
			printf("对不起,查找不到此学生!\n");
	}
}
void menu1()//学生菜单
{
	printf("-------------------------------【学分信息系统】--------------------------------------\n");
	printf("\n");
	printf("				0.查看学分信息										   \n");
	printf("				1.修改学生密码										   \n");
	printf("				2.退出学生系统										   \n");
	printf("-------------------------------------------------------------------------------------\n");
}
void menu2()
{
	//所有操作都同步到文件
	printf("---------------------------------【学分信息管理系统】-------------------------------------\n");
	printf("\n");
	printf("				0.录入学生信息										   \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("				9.浏览全部学生信息									   \n");
	printf("				10.统计学生信息										   \n");
	printf("				11.密码管理											   \n");
	printf("				12.退出系统											   \n");
	printf("				13.保存文件											   \n");
	printf("------------------------------------------------------------------------------------------\n");
}
void keydown1(int num)//学生选择操作
{
	int choice;
	scanf_s("%d", &choice);
	switch (choice)
	{
	case 0:printf("--------------------------------------【查看学分信息】--------------------------------------\n");
		printf("姓名\t学号\t班级号\t基础类课程\t专业基础类课程\t专业类课程\t专业选修课程\t实践课程\t总学分\n");
		stuview(num);
		break;
	case 1:printf("--------------------------------------【修改学生密码】--------------------------------------\n");
		stupasswordrevise(num);
		break;
	case 2:printf("--------------------------------------【退出学生系统】--------------------------------------\n");
		printf("正常退出!\n");
		system("pause");
		exit(0);
		break;
	default:
		printf("输入错误!\n");
		break;
	}	
}
void keydown2(struct student* list)
{
	int num, classnum, subnum;
	struct student* stu = (struct student*)malloc(sizeof(struct student));
	int choice;
	scanf_s("%d", &choice);
	switch (choice)
	{
	case 0:
		printf("--------------------------------------【录入学生信息】--------------------------------------\n");
		printf("请输入学生学号、姓名、班级号、基础类课程学分、专业基础类课程学分、专业类课程学分、专业选修学分、实践类课程学分、学生密码:\n");
		fflush(stdin);//清空缓冲区
		inputstu(stu);
		insertnode(list, stu);
		break;
	case 1:
		printf("--------------------------------------【修改学生信息】--------------------------------------\n");
		printf("请输入您需要修改的学生学号:\n");
		scanf_s("%d", &num);
		revise(list, num);//按学号查找并修改学生信息
		break;
	case 2:
		printf("--------------------------------------【删除学生信息】--------------------------------------\n");
		printf("请输入您需要删除的学生学号:\n");
		scanf_s("%d", &num);
		deletenode(list, num);
		break;
	case 3:
		printf("--------------------------------------【按学号查询学生信息】--------------------------------------\n");
		printf("请输入你要查找的学号:\n");
		scanf_s("%d", &num);
		searchnode1(list, num);//按学号查找结点
		break;
	case 4:
		printf("--------------------------------------【输入班级号,按照学号顺序输出学生信息】--------------------------------------\n");
		printf("请输入你要查找的班级号:\n");
		scanf_s("%d", &classnum);
		searchnode2(list, classnum);//按班级号查找(按学号大小显示一个班级的情况)
		break;
	case 5:
		printf("--------------------------------------【输入班级号,按照拼音顺序顺序输出学生信息】--------------------------------------\n");
		printf("请输入你要查找的班级号:\n");
		scanf_s("%d", &classnum);
		searchnode3(list, classnum);//按班级号查找(按姓名拼音顺序输出学生信息)
		break;
	case 6:
		printf("--------------------------------------【输入课程号,输出未达标学生信息】--------------------------------------\n");
		printf("请输入您要查询的课程号:\n");
		scanf_s("%d", &subnum);
		searchnode4(list, subnum);//输入课程号,输出未达标学生信息
		break;
	case 7:
		printf("--------------------------------------【查询满足毕业条件的学生信息】--------------------------------------\n");
		allqualifiedstu(list);//打印所有可以毕业的学生信息
		break;
	case 8:
		printf("--------------------------------------【浏览本次学生信息】--------------------------------------\n");
		printlist(list);
		break;
	case 9:
		printf("--------------------------------------【浏览全部学生信息】--------------------------------------\n");
		readfile("stu.txt");
		break;
	case 10:
		printf("--------------------------------------【统计学生信息】--------------------------------------\n");
		stustatistic(list);
		break;
	case 11:
		printf("--------------------------------------【密码管理】--------------------------------------\n");
		stupasswordmanage(list);
		break;
	case 12:
		printf("--------------------------------------【退出系统】--------------------------------------\n");
		printf("正常退出!\n");
		system("pause");
		exit(0);
		break;
	case 13:
		printf("--------------------------------------【保存文件】--------------------------------------\n");
		save("1.txt");//将以上操作保存到最终的学生文件里面
		break;
	default:
		printf("选择错误!请重新输入\n");
		system("pause");
		break;
	}
	writefile(list, "1.txt");
}

void readfile(char *filename)//从文件中读取信息并显示出来
{
	struct student a;
	FILE* fp;
	fp = fopen("stu.txt", "r");//以只读方式打开文件
	if (fp == NULL)
	{
		printf("文件无法打开!\n");
		exit(1);//异常退出
	}
	else {
		while (!feof(fp))
		{
		fscanf(fp, "%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%s\n", &a.num, a.name, &a.classnum, &a.credit[0], &a.credit[1], &a.credit[2], &a.credit[3], &a.credit[4], &a.allcredit, a.password);
		outputstu(&a);
		}
	}
	fclose(fp);
}
void save(char* filename)//将信息保存到最终的文件stu.txt里
{
	struct student a;
	FILE* fp = fopen(filename, "r");//以只读的方式打开文件
	FILE* fpw = fopen("stu.txt", "a+");//以追加的方式打开文件,将数据追加到文件末尾
	if (fp == NULL)
	{
		printf("文件无法打开!\n");
		exit(1);//异常退出
	}
	else {
		while (!feof(fp))
		{
			fscanf(fp, "%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%s\n", &a.num, a.name, &a.classnum, &a.credit[0], &a.credit[1], &a.credit[2], &a.credit[3], &a.credit[4], &a.allcredit, a.password);
			fprintf(fpw, "%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%s\n", a.num, a.name, a.classnum, a.credit[0], a.credit[1], a.credit[2], a.credit[3], a.credit[4], a.allcredit, a.password);
		}
	}
	fclose(fp);
	fclose(fpw);
}
void writefile(struct student* headnode, char* filename)//从链表中读取文件,追加进文本.txt里
{
	FILE* fp;
	fp = fopen(filename, "w");
	if (fp == NULL) {
		printf("文件打开失败!\n");
	}
	struct student* pmove = headnode->next;
	while (pmove) {
		fprintf(fp, "%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%s\n", pmove->num, pmove->name, pmove->classnum, pmove->credit[0], pmove->credit[1], pmove->credit[2], pmove->credit[3], pmove->credit[4], pmove->allcredit, pmove->password);
		pmove = pmove->next;
	}
	fclose(fp);
}

总结与心得

学分管理系统主要分为两个部分,一部分是学生,一部分是管理员。要实现管理员的操作功能主要通过链表实现,管理员每次对链表进行操作都同步到文件,所以只需要知道一个链表的表头就能实现对链表的增删改查等功能;要实现学生功能主要是对文件本身直接操作,结合实际,我认为学生只有两个操作权限,一是查看自己的信息,二是修改自己的密码,学生修改密码时需要对文件本身进行操作。

1、学生信息的录入、修改、删除、查找其实都是对链表进行操作,设置一个表头和结构体指针,遍历链表,分别实现相应功能,这部分内容较为简单,没有遇到大的问题。

2、查询学生信息主要分为四个功能,为了使程序看起来简洁,我分为四个小函数写,其中输入班级号按照学号顺序输出学生信息主要用到冒泡排序,姓名拼音顺序直接调用strcmp函数和冒泡排序即可。

3、学生自行修改密码,主要是对文件本身进行操作,由于对文件操作不熟悉,这部分内容我写了很久,调试过很多次,最后选择以创建新文件的形式完成密码的修改及信息保存——即打开一个文件,对其进行读取,当读取到目标结构体时,对其进行修改,修改后将其写入另一个新建的文本,如果没有进行修改,则直接将原文本的结构体内容写入新文本,最后删除原文本,并对新文本重命名即可。

这次程序设计实践主要让我对链表和结构体的运用更加熟练,最重要的是我学会了操作文件。其实静下心来先把课本上关于文件的基础知识过一遍,文件操作的内容并不难,所以静下心来学习很重要,一味赶进度效率低而且容易导致心情烦躁。

这次实践感触最深的是没有早点开始写大作业,导致在期末复习周带着焦虑的心情写代码。通过这次实践,我想我以后会更加注重小组成员之间的交流与合作,也会学着规划自己的时间,不再将任务都留到ddl,学着更加合理地为组员安排任务…总之,这次程序实践,收获很大,既有学习能力上的,也有思维上的。

你可能感兴趣的:(C语言,c语言,链表,数据结构)