如何用C语言写一个简单的教务管理系统

这篇具有很好参考价值的文章主要介绍了如何用C语言写一个简单的教务管理系统。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

教务管理系统

一、项目需求

本项目管理三种身份人员的信息:

  1. 管理员(仅一个):姓名:admin 密码:
  2. 教师(多个):姓名、密码、工号、性别、出生日期、
  3. 学生(多个):姓名、密码、学号、性别、出生日期、数学、语文、英语三门功课成绩

管理员登录后可以进行如下操作:

  1. 修改自身登录密码
  2. 添加新教师
  3. 查看所有教师
  4. 删除教师
  5. 修改教师信息

教师登录后可以进行如下操作:

  1. 修改自身登录密码
  2. 查阅自身信息
  3. 添加新学生
  4. 删除学生
  5. 查阅指定学生信息
  6. 修改学生信息(姓名、性别、出生日期、三门功课成绩)
  7. 按学号从低到高查看所有学生信息
  8. 按数学成绩从高到低查看所有学生信息
  9. 按语文成绩从高到低查看所有学生信息
  10. 按英语成绩从高到低查看所有学生信息
  11. 按总分从高到低查看所有学生信息

学生登录后可以进行如下操作:

  1. 修改自身登录密码
  2. 查阅自身信息

二、设计思路

  1. 可以先设计管理员的功能
  2. 设计老师的功能
  3. 设计学生的功能`

三、功能实现

1、数据类型可以选择结构体
2、数据结构可以选用带头结点的链表来存储

一、管理员功能实现

#pragma once

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
struct adm
{
	char name[20];
	char ser[20];

};
struct teacher
{
	char name[20];
	char ser[20];
	int num;
	char sex[10];
	char bir[20];
	struct teacher*next;
};

上面就是我们定义好的结构体,定义好了数据类型我们可以开始搭建框架了。

二、管理员分支函数框架

void adm_info(void)
{
	int x=1;
	struct adm s = my_read();
	struct teacher *head = NULL;
	head = create_node();
	head = teacher_read();
	while(x)
	{
		printf("———————————————————————————————————————\n");
		printf("欢迎来到管理员登陆界面!\n");	
		printf("请输入姓名:");
		char name[20];
		scanf("%s",name);
		while(getchar() !='\n');
		printf("请输入密码:");
		char ser[20];
		scanf("%s",ser);
		while(getchar() !='\n');
		printf("身份确认中...\n");
		if(strcmp(s.name,name)==0&&strcmp(s.ser,ser)==0)
		{
			printf("登陆成功!\n");
			break;
		}
		printf("信息有误,请核实姓名和密码!\n");
		printf("———————————————————————————————————————\n");
		return;
	}
	int flag = 1,set,n;
	while(flag)
	{
		printf("——————————————————————————————————\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("|0、返回上一层!                 |\n");
		printf("+————————————————————————————————+\n");
		printf("输入您的选择:                   |\n");
		printf("——————————————————————————————————\n");
		scanf("%d",&set);
		while(getchar() != '\n');
		switch(set)
		{
			case 1:mod_ser(&s);break;
			case 2:add_teacher(head);break;
			case 3:show_teacher(head);
				   printf("任意健退出显示,返回上一层!\n");
				   scanf("%d",&n);
				   while(getchar() != '\n');
				   break;
			case 4:del_teacher(head);break;
			case 5:mod_teacher(head);break;
			case 0:flag = 0;break;
			default:printf("无该选项!\n");break;
		}
	}
	adm_write(s);
	teacher_write(head);
	return;
}

2.1 函数分析

1、函数的框架是先进入登陆界面
2、利用分支结构实现管理员的功能

2.2、登录功能实现

1、想实现登录功能我们需要记住管理员的账号和密码,通过比较是否相等,从而实现这个功能。
2、此处就需要用到文件I/O的相关知识了,

2.3、管理员信息的文件保存与读写函数

//保存管理员密码信息 0成功-1失败
int adm_write(struct adm s)
{
	FILE*fp = NULL;
	fp = fopen("./adm.txt","w");//打开文件
	assert(fp != NULL);

	int ret;
	ret = fprintf(fp,"%s %s\n",s.name,s.ser);//把数据传到文件中
	if(ret != EOF)
	{
		printf("保存管理员数据成功!\n");
		fclose(fp);//关闭文件
		return 0;
	}
	return -1;
}
//读管理员密码
struct adm my_read()
{
	FILE*fp = NULL;
	fp = fopen("./adm.txt","r");//打开文件
	assert(fp != NULL);
	struct adm a;
	int ret;
	ret = fscanf(fp,"%s%s",a.name,a.ser);//读文件
	if(ret != EOF)
	printf("读取管理员数据成功!\n");
	fclose(fp);//关闭文件
	return a;//返回数据
}

2.4、修改管理员密码

//修改管理员密码
void mod_ser(struct adm*s)
{
	printf("请输入想修改的密码:");
	scanf("%s",s->ser);
	while(getchar() !='\n');
	printf("修改成功!\n");
	return;

}

下一步就是设置跟老师相关的参数了,我们需要写一个创建老师信息的节点函数和使用头插法插入老师信息的函数。

2.5、添加老师信息

//创建老师结构体节点
struct teacher *create_node()
{
	struct teacher *p = NULL;
	p = (struct teacher*)malloc(sizeof(struct teacher));//申请堆空间
	assert(p != NULL);//条件为真执行否则段错误
	p->next = NULL;
	return p;//返回地址
}
//带头节点的链表来添加老师信息
void add_teacher(struct teacher*head)
{
	int flag = 1;
	struct teacher *p = NULL;
	p = head->next;
	struct teacher *pnew = NULL;
	pnew = create_node();
	printf("请输入老师姓名:");
	scanf("%s",pnew->name);
	while(getchar() != '\n');
	printf("请输入老师密码:");
	scanf("%s",pnew->ser);
	while(getchar() != '\n');
	while(flag)	//防止工号重复
	{
	
		printf("请输入工号:");
		scanf("%d",&pnew->num);
		while(getchar() != '\n');
		p = head->next;
		while(p!= NULL)
		{
			if(p->num == pnew->num)//找到相等的工号p就停止
			{
				break;
			}
			p = p->next;
		}
		if(NULL != p)//说明重复
		{
			flag = 1;
		}
		else
		{
			break;
		}
	}
	printf("请输入性别:");
	scanf("%s",pnew->sex);
	while(getchar() != '\n');
	printf("请输入出生日期例如(19980312):");
	scanf("%s",pnew->bir);
	while(getchar() != '\n');
	//头插法插入数据
	pnew->next = head->next;
	head->next = pnew;
	printf("添加老师信息成功!\n");
	return;
}

因为涉及到后面的老师登录,和修改老师信息所以我们,还需要做一个读写老师数据到文件的函数。

2.6、老师信息的文件I/O函数

//读取老师信息
struct teacher*teacher_read()
{
	FILE*fp = NULL;
	fp = fopen("./teacher.txt","r");
	assert(fp != NULL);
//开始读取数据
	int ret;
	struct teacher *pnew = NULL,*head = NULL,*newhead = NULL;

	head = create_node();
	while(1)
	{
		pnew = create_node();//创建新的节点
		ret = fscanf(fp,"%s%s%d%s%s",pnew->name,pnew->ser,&pnew->num,pnew->sex,pnew->bir);
		if(ret == EOF)//ret == EOF读取到末尾
		{
			break;
		}

		pnew->next = newhead;
		newhead = pnew;
	}
	free(pnew);//释放多出来的一个节点
	fclose(fp);
	printf("读取老师数据成功!\n");
	head->next = newhead;
	return head;
	
}

//保存老师的数据
int teacher_write(struct teacher*head)
{
	FILE*fp = NULL;//打开文件
	fp = fopen("./teacher.txt","w");
	assert(fp != NULL);

	int ret;
	struct teacher *p = head->next;
	while(p != NULL)
	{
		ret = fprintf(fp,"%s\t%s\t%d\t%s\t%s\n",p->name,p->ser,p->num,p->sex\
						,p->bir);//写操作
		if(ret == EOF)
		{
			break;
		}
		p = p->next;
	}
	if(p == NULL)
	printf("保存老师数据成功!\n");
	fclose(fp);//关闭文件
	return 0;
}

添加信息后,当然需要可以显示和查找老师的信息咯。所以接下来就来实现这两个功能吧

2.7、老师信息的查找和显示

//带头节点显示老师的信息
void show_teacher(struct teacher *head)
{
	if(head->next == NULL)//入参检测
	{
		printf("无老师信息!\n");
	}
	struct teacher *p = head->next;
	while(p!= NULL)
	{
		printf("姓名:%s\t密码:%s\t工号:%d\t性别:%s\t出生:%s\n",p->name,\
						p->ser,p->num,p->sex,p->bir);
		p = p->next;
	}
	return ;
}
//通过工号查找老师的信息
struct teacher*search_teacher(struct teacher*head,int num)
{
	struct teacher *ps = NULL,*p = NULL;
	p = head->next;
	while(p != NULL)
	{
		if(p->num == num)
		{
			ps = p;
		}
		p = p->next;
	}
	if(ps == NULL)
	{
		printf("无该老师信息!\n");
	}
	return ps;
	
}

可以添加可以查找可以显示,但是我们还缺少编辑老师信息的函数,所以接下来可以创建删除老师信息,和修改老师信息的函数。

2.8、老师信息的删除

//通过工号删除老师信息
void del_teacher(struct teacher*head)
{
	struct teacher *pdel = NULL,*p = NULL;
	p = head->next;
	if(p ==NULL)
	{
		printf("无老师信息无法删除!\n");
		return;
	}
	int num;
	printf("请输入想删除老师工号:");
	scanf("%d",&num);
	while(p != NULL)
	{
		if(p->num == num)
		{
			pdel = p;
			break;
		}
		p = p->next;
	}
	//头删
	if(pdel == head->next)
	{
		head->next = pdel->next;
		printf("删除成功!\n");
		free(pdel);
		return ;
	}
	//尾删中间删
	p = head->next;
	while(p != NULL)
	{
		if(p->next == pdel)
		{
			break;
		}
		p = p->next;
	}
	p->next = pdel->next;
	free(pdel);//释放删掉的节点
	printf("删除成功!\n");
	return;
}

2.9、老师信息各项的单独修改

分析:其实从标题就可以看出因为需要有选择的修改,所以需要用到分支结构,然后通过选择实现单独的修改操作,无非就是一个子菜单了。

//修改老师信息
void mod_teacher(struct teacher*head)
{
	printf("请输入想修改老师的工号:");
	int num;
	scanf("%d",&num);
	struct teacher *pmod = NULL;
	pmod = search_teacher(head,num);
	int set,flag = 1;
	while(flag)
	{
		printf("+———————————————————+\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("|0 返回上一层       |\n");
		printf("+———————————————————+\n");
		printf(" 请输入你的选择:");
		scanf("%d",&set);
		while(getchar() != '\n');
		switch(set)
		{
			case 1:printf("输入新的姓名:");
				   scanf("%s",pmod->name);
				   while(getchar() != '\n');
				   break;
			case 2:printf("输入新的密码:");
				   scanf("%s",pmod->ser);
				   while(getchar() != '\n');
				   break;
			case 3:printf("输入新的性别:");
				   scanf("%s",pmod->sex);
				   while(getchar() != '\n');
				   break;
			case 4:printf("输入新的生日:");
				   scanf("%s",pmod->bir);
				   while(getchar() != '\n');
				   break;
			case 0:flag = 0;break;
			default:printf("无此功能!\n");break;
		}
	}

}

小结

到目前为止我们已经写好了管理者这个小分支的所有功能了,目前我们能做到的功能有如下:
1、加载管理员的信息和保存管理员的信息。
2、加载老师和保存老师的信息
3、修改和添加老师的信息。

三、老师分支函数的创建

3.1、函数分析

1.修改自身登录密码
2. 查阅自身信息
2. 添加新学生
3. 删除学生
4. 查阅指定学生信息
5. 修改学生信息(姓名、性别、出生日期、三门功课成绩)
6. 按学号从低到高查看所有学生信息
7. 按数学成绩从高到低查看所有学生信息
8. 按语文成绩从高到低查看所有学生信息
9. 按英语成绩从高到低查看所有学生信息
10. 按总分从高到低查看所有学生信息
从功能上我们不难看出我们需要先进行一个登录,这里就需要加载之前保存好的老师数据,我们已经写好,然后需要对学生进行操作,很明显需要定义关于学生的结构体,整体的框架跟管理员的并没有什么不同,想好了就可以直接动手敲代码了。

3.2、创建学生的结构体

#pragma  once
#include"adm.h"
struct stu
{
	char name[30];
	char ser[30];
	int num;
	char sex[10];
	char bir[15];
	float math;
	struct stu*next;
	float chinese;
	float english;
};
typedef struct stu  STU;

因为需要用到管理员里面的一些函数所以之前创建好的函数一定要都在管理员.h文件进行声明,这样老师分支这边调用只需要包含管理员那边的头文件即可,避免重复劳动。

3.3、老师分支的函数主框架

void teacher_info()
{
	int x=1;
	struct teacher *head = NULL;
	head = create_node();
	head = teacher_read();
	STU*stu_head = NULL;
	stu_head = create_stu_node();
	stu_head = read_stu();
	TEACH*s = NULL;
	while(x)
	{
		printf("———————————————————————————————————————\n");
		printf("欢迎来到老师登陆界面!\n");	
		printf("请输入工号:");
		int num;
		scanf("%d",&num);
		while(getchar() !='\n');
		printf("请输入密码:");
		char ser[20];
		scanf("%s",ser);
		while(getchar() !='\n');
		printf("身份确认中...\n");
		s = search_teacher(head,num);
		if(NULL == s)
		{
			printf("登陆失败!\n");
			return;
		}
		if(s->num == num && strcmp(s->ser,ser)==0)
		{
			printf("登陆成功!\n");
			x = 0;
			break;
		}
		else
		{
			printf("信息有误,请核实工号和密码!\n");
			printf("———————————————————————————————————————\n");
			return;
		}
	}
	int flag = 1,set,n;
	while(flag)
	{
		printf("——————————————————————————————————————————————\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("|7、 按学号从低到高查看所有学生信息           |\n");
		printf("——————————————————————————————————————————————\n");
		printf("|8、 按数学成绩从高到低查看所有学生信息       |\n");
		printf("——————————————————————————————————————————————\n");
		printf("|9、 按语文成绩从高到低查看所有学生信息       |\n");
		printf("——————————————————————————————————————————————\n");
		printf("|10、按英语成绩从高到低查看所有学生信息       |\n");
		printf("——————————————————————————————————————————————\n");
		printf("|11、按总分从高到低查看所有学生信息           |\n");
		printf("——————————————————————————————————————————————\n");
		printf("|0、 返回上一层                               |\n");
		printf("——————————————————————————————————————————————\n");
		printf("输入您的选择:");
		scanf("%d",&set);
		while(getchar() != '\n');
		switch(set)
		{
			case 1:mod_teacher_ser(s);break;
			case 0:flag = 0;break;
			case 2:
					printf("姓名:%s\t密码:%s\t工号:%d\t性别:%s\t出生:%s\n",\
					s->name,s->ser,s->num,s->sex,s->bir);break;
			case 3:add_stu_info(stu_head);break;
			case 5:show_stu_info_by_num(stu_head);break;
			case 4:del_stu_info(stu_head);break;
			case 6:mod_stu_info_by_num(stu_head);break;
			case 7:sortup_by_num(stu_head);
				   printf("任意健退出显示,返回上一层!");
				   scanf("%d",&n);
				   while(getchar() != '\n');
				   break;
			case 8:sortdown_by_math(stu_head);
				   printf("任意健退出显示,返回上一层!\n");
				   scanf("%d",&n);
				   while(getchar() != '\n');
				   break;
			case 9:sortdown_by_chinese(stu_head);
				   printf("任意健退出显示,返回上一层!\n");
				   scanf("%d",&n);
				   while(getchar() != '\n');
				   break;
			case 10:sortdown_by_english(stu_head);
				   printf("任意健退出显示,返回上一层!\n");
				   scanf("%d",&n);
				   while(getchar() != '\n');
				   break;
			case 11:sortdown_by_allscore(stu_head);
				   printf("任意健退出显示,返回上一层!\n");
				   scanf("%d",&n);
				   while(getchar() != '\n');
				   break;
			default:printf("没有这个功能!\n");break;
		}
	}
	teacher_write(head);
	write_stu(stu_head);
	return;
}

同样也是先登录成功,然后在进行后续的功能,前面有思路分析这里就不赘述了。

3.4、老师分支修改自身密码

#include "teacher.h"
//修改老师密码
void mod_teacher_ser(TEACH*p)
{
	printf("请输入新的密码:");
	scanf("%s",p->ser);
	while(getchar() != '\n');
	printf("修改成功!\n");
	return ;
}

3.5、添加学生信息

//创建学生节点
STU*create_stu_node()
{
	STU*pnew = NULL;
	pnew = (STU*)malloc(sizeof(STU));
	assert(pnew != NULL);
	pnew->next = NULL;
	return pnew;
}
//增加学生信息带头节点
void add_stu_info(STU*stu_head)
{
	STU*pnew = NULL;
	pnew = create_stu_node();
	printf("请输入学生姓名:");
	scanf("%s",pnew->name);
	while(getchar() != '\n');
	printf("请输入学生密码:");
	scanf("%s",pnew->ser);
	while(getchar() != '\n');
	int flag = 1;
	STU*p = stu_head->next;
	while(flag)	//防止学号重复
	{
	
		printf("请输入学号:");
		scanf("%d",&pnew->num);
		while(getchar() != '\n');
		p = stu_head->next;
		while(p!= NULL)
		{
			if(p->num == pnew->num)
			{
				break;//重复就退出循环
			}
			p = p->next;
		}
		if(NULL == p)//不重复退出循环
		{
			break;
		}
	}
	printf("请输入性别:");
	scanf("%s",pnew->sex);
	while(getchar() != '\n');
	printf("请输入出生日期例如(1998-03-12):");
	scanf("%s",pnew->bir);
	while(getchar() != '\n');
	printf("请输入数学成绩:");
	scanf("%f",&pnew->math);
	while(getchar() != '\n');
	printf("请输入语文成绩:");
	scanf("%f",&pnew->chinese);
	while(getchar() != '\n');
	printf("请输入英语成绩:");
	scanf("%f",&pnew->english);
	while(getchar() != '\n');
	// 头插
	pnew->next = stu_head->next;
	stu_head->next = pnew;
	printf("添加学生信息成功!\n");
	return ;
}

这里其实有一个比较重要的点就是如何防止学号重复,这里简单的分析一下提供几个思路:
1、可以考虑用全局静态变量,每次读取,或者添加一个学生数据就自增一下,删除就自减。
2、可以考虑添加一个判断,学号重复就递归调用本身,不重复就执行下一步。
3、就是我用的方法,直接循环解决问题。

3.6、学生信息的文件I/O操作

//写学生信息到文件
int write_stu(STU*head)
{
	FILE*fp = NULL;//打开文件
	fp = fopen("./student.txt","w");
	assert(fp != NULL);

	int ret;
	STU *p = head->next;
	while(p != NULL)//写操作
	{
		ret = fprintf(fp,"%s\t%s\t%d\t%s\t%s\t%.2f\t%.2f\t%.2f\n"\
		,p->name,p->ser,p->num,p->sex,p->bir,p->math,p->chinese,p->english);
		if(ret == EOF)
		{
			break;
		}
		p = p->next;
	}
	if(p == NULL)
	printf("保存学生数据成功!\n");
	fclose(fp);//关闭文件
	return 0;
}
//读学生文件操作
STU*read_stu()
{
	FILE*fp = NULL;//打开文件
	fp = fopen("./student.txt","r");
	assert(fp != NULL);

	int ret;
	STU *pnew = NULL,*head = NULL,*newhead = NULL;

	head = create_stu_node();//创建一个头节点
	while(1)
	{
		pnew = create_stu_node();//新的节点接受数据
		ret = fscanf(fp,"%s%s%d%s%s%f%f%f",\
		pnew->name,pnew->ser,&pnew->num,pnew->sex,\
		pnew->bir,&pnew->math,&pnew->chinese,&pnew->english);
		if(ret == EOF)//读到末尾
		{
			break;
		}
//头插
		pnew->next = newhead;
		newhead = pnew;
	}
	free(pnew);//释放多余的节点
	fclose(fp);//关闭文件
	printf("读取学生数据成功!\n");
	head->next = newhead;
	return head;
}

3.7、删除学生信息通过学号

//删除学生信息
void del_stu_info(STU*head)
{
	STU *pdel = NULL,*p = NULL;
	p = head->next;//入参检查
	if(p ==NULL)
	{
		printf("无学生信息无法删除!\n");
		return;
	}
	int num;
	printf("请输入想删除学生学号:");
	scanf("%d",&num);
	while(getchar() != '\n');
	while(p != NULL)
	{
		if(p->num == num)
		{
			pdel = p;
			break;//找到目标
		}
		p = p->next;
	}
//	pdel = search_teacher(head,num);
	if(pdel == head->next)//头删
	{
		head->next = pdel->next;
		printf("删除学生信息成功!\n");
		free(pdel);
		return ;
	}
	p = head->next;
	//中间删和尾删
	while(p != NULL)
	{
		if(p->next == pdel)
		{
			break;
		}
		p = p->next;
	}
	p->next = pdel->next;
	free(pdel);//释放删除的节点
	printf("删除学生信息成功!\n");
	return;

}

其实这里只提供了一种方法,还可以考虑通过名字,或者其他的方式,但是因为我们设定学号不可以重复具有唯一性,所以选择了这个方法。

3.8、学生信息的查找

//通过学号显示特定学生的信息
void show_stu_info_by_num(STU*head)
{
	if(head->next == NULL)//入参检查
	{
		printf("还没有这个学生信息!\n");
		return;
	}
	printf("请输入想查找的学生学号:");
	int num;
	scanf("%d",&num);
	while(getchar() != '\n');

	STU*p = NULL;
	p = head->next;
	STU*ps = NULL;
	while(p != NULL)
	{
		if(p->num == num)
		{
			ps = p;//找到目标
			break;
		}
		p = p->next;
	}
	//显示
	if(ps != NULL)
	{
		printf("姓名:%s\t密码:%s\t学号:%d\t性别:%s\t出生:%s\t数学分数:%.2f\t语文分数:%.2f\t英语分数%.2f\n",p->name,p->ser,p->num,p->sex,p->bir,\
						p->math,p->chinese,p->english);
		return ;
	}
	printf("没有这个学生信息!\n");
	return;
}

同样的原因我们还是使用学号作为查找依据。

3.9、学生信息的修改

//修改学生信息通过学号
void mod_stu_info_by_num(STU*head)
{
	printf("请输入想修改学生的学号:");
	int num;
	scanf("%d",&num);
	while(getchar() !='\n'); 
	STU *pmod = NULL;
	if(head->next == NULL)//入参检测
	{
		printf("还没有这个学生!\n");
		return;
	}

	STU*p = NULL;
	p = head->next;
	while(p != NULL)
	{
		if(p->num == num)
		{
			pmod = p;//找到目标
			break;
		}
		p = p->next;
	}
	int set,flag = 1;
	while(flag)
	{
		printf("——————————————————————————\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("|7 修改英语成绩          |\n");
		printf("——————————————————————————\n");
		printf("|0 返回上一层            |\n");
		printf("——————————————————————————\n");
		printf("|请输入你的选择          |\n");
		printf("——————————————————————————\n");
		scanf("%d",&set);
		switch(set)
		{
			case 1:printf("输入新的姓名:");
				   scanf("%s",pmod->name);
				   while(getchar() != '\n');
				   break;
			case 2:printf("输入新的密码:");
				   scanf("%s",pmod->ser);
				   while(getchar() != '\n');
				   break;
			case 3:printf("输入新的性别:");
				   scanf("%s",pmod->sex);
				   while(getchar() != '\n');
				   break;
			case 4:printf("输入新的生日:");
				   scanf("%s",pmod->bir);
				   while(getchar() != '\n');
				   break;
			case 5:printf("输入新的数学成绩:");
				   scanf("%f",&pmod->math);
				   while(getchar() != '\n');
				   break;
			case 6:printf("输入新的语文成绩:");
				   scanf("%f",&pmod->chinese);
				   while(getchar() != '\n');
				   break;
			case 7:printf("输入新的英语成绩:");
				   scanf("%f",&pmod->english);
				   while(getchar() != '\n');
				   break;
			case 0:flag = 0;break;
			default:printf("无此功能!\n");break;
		}
	}
	printf("修改学生信息成功!\n");
	return;
}

这个和管理员修改老师信息一样,我们同样做了一个子菜单方便操作。

3.9、排序

其实无论是根据什么排序原理其实都差不多,无非是改变一下判别条件,这边就不做详细的介绍了。

//学号升序
void sortup_by_num(STU*head)
{
	if(head->next == NULL)
	{
		printf("还没有学生信息!\n");
		return;
	}
	STU*head1 = head->next;
	STU*p = NULL;
	STU*pmax = NULL;
	head->next = NULL;
	STU*newhead = NULL;
	/*排序*/
	while(head1 != NULL)
	{
		p = head1;
		pmax = head1;
		while(p != NULL)
		{
			if(pmax->num < p->num)//找出最大值
			{
				pmax = p;
			}
			p = p->next;
		}
		if(pmax == head1)//移除最大值
		{
			head1 = head1->next;
		}
		else
		{
			p = head1;
			while(p->next != pmax)
			{
				p = p->next;
			}
			p->next = pmax->next;
		}
		/*插入最大值*/
		pmax->next = NULL;
		pmax->next = newhead;
		newhead = pmax;		
	}
	head->next = newhead;
	/*展示排序后的链表*/
	p = head->next;
	printf("学号从低到高开始显示!\n");
	while(p != NULL)
	{
		printf("姓名:%s\t密码:%s\t学号:%d\t性别:%s\t出生:%s\t数学分数:%.2f\t语文分数:%.2f\t英语分数%.2f\n",\
			   p->name,p->ser,p->num,p->sex,p->bir,p->math,p->chinese,p->english);
		p = p->next;
	}

	return;

}
//数学成绩降序排列
void sortdown_by_math(STU*head)
{
	if(head->next == NULL)
	{
		printf("还没有学生信息!\n");
		return;
	}
	STU*head1 = head->next;
	STU*p = NULL;
	STU*pmin = NULL;
	head->next = NULL;
	STU*newhead = NULL;
	/*排序*/
	while(head1 != NULL)
	{
		p = head1;
		pmin = head1;
		while(p != NULL)
		{
			if(pmin->math > p->math)//找出最大值
			{
				pmin = p;
			}
			p = p->next;
		}
		if(pmin == head1)//移除最大值
		{
			head1 = head1->next;
		}
		else
		{
			p = head1;
			while(p->next != pmin)
			{
				p = p->next;
			}
			p->next = pmin->next;
		}
		/*插入最大值*/
		pmin->next = NULL;
		pmin->next = newhead;
		newhead = pmin;		
	}
	head->next = newhead;
	/*展示排序后的链表*/
	p = head->next;
	printf("数学成绩从高到底开始显示!\n");
	while(p != NULL)
	{
		printf("姓名:%s\t密码:%s\t学号:%d\t性别:%s\t出生:%s\t数学分数:%.2f\t语文分数:%.2f\t英语分数%.2f\n",p->name,p->ser,p->num,p->sex,p->bir,\
						p->math,p->chinese,p->english);
		p = p->next;
	}
	return;
}
//语文成绩降序排列
void sortdown_by_chinese(STU*head)
{
	if(head->next == NULL)
	{
		printf("还没有学生信息!\n");
		return;
	}
	STU*head1 = head->next;
	STU*p = NULL;
	STU*pmin = NULL;
	head->next = NULL;
	STU*newhead = NULL;
	/*排序*/
	while(head1 != NULL)
	{
		p = head1;
		pmin = head1;
		while(p != NULL)
		{
			if(pmin->chinese > p->chinese)//找出最大值
			{
				pmin = p;
			}
			p = p->next;
		}
		if(pmin == head1)//移除最大值
		{
			head1 = head1->next;
		}
		else
		{
			p = head1;
			while(p->next != pmin)
			{
				p = p->next;
			}
			p->next = pmin->next;
		}
		/*插入最大值*/
		pmin->next = NULL;
		pmin->next = newhead;
		newhead = pmin;		
	}
	head->next = newhead;
	/*展示排序后的链表*/
	p = head->next;
	printf("语文成绩从高到底开始显示!\n");
	while(p != NULL)
	{
		printf("姓名:%s\t密码:%s\t学号:%d\t性别:%s\t出生:%s\t数学分数:%.2f\t语文分数:%.2f\t	英语分数%.2f\n",\
		p->name,p->ser,p->num,p->sex,p->bir,p->math,p->chinese,p->english);
		p = p->next;
	}
	return;


}
//英语成绩降序排列
void sortdown_by_english(STU*head)
{
	if(head->next == NULL)
	{
		printf("还没有学生信息!\n");
		return;
	}
	STU*head1 = head->next;
	STU*p = NULL;
	STU*pmin = NULL;
	head->next = NULL;
	STU*newhead = NULL;
	/*排序*/
	while(head1 != NULL)
	{
		p = head1;
		pmin = head1;
		while(p != NULL)
		{
			if(pmin->english > p->english)//找出最大值
			{
				pmin = p;
			}
			p = p->next;
		}
		if(pmin == head1)//移除最大值
		{
			head1 = head1->next;
		}
		else
		{
			p = head1;
			while(p->next != pmin)
			{
				p = p->next;
			}
			p->next = pmin->next;
		}
		/*插入最大值*/
		pmin->next = NULL;
		pmin->next = newhead;
		newhead = pmin;		
	}
	head->next = newhead;
	/*展示排序后的链表*/
	p = head->next;
	printf("英语成绩从高到底开始显示!\n");
	while(p != NULL)
	{
		printf("姓名:%s\t密码:%s\t学号:%d\t性别:%s\t出生:%s\t数学分数:%.2f\t语文分数:%.2f\t		英语分数%.2f\n",p->name,p->ser,p->num,p->sex,p->bir,p->math,p->chinese,p->english);
		p = p->next;
	}
	return;
}
//总分降序排列
void sortdown_by_allscore(STU*head)
{
	if(head->next == NULL)
	{
		printf("还没有学生信息!\n");
		return;
	}
	STU*head1 = head->next;
	STU*p = NULL;
	STU*pmin = NULL;
	head->next = NULL;
	STU*newhead = NULL;
	/*排序*/
	while(head1 != NULL)
	{
		p = head1;
		pmin = head1;
		while(p != NULL)
		{
			if(pmin->english+pmin->math+pmin->chinese > p->math+p->chinese+p->english)//找出最大值
			{
				pmin = p;
			}
			p = p->next;
		}
		if(pmin == head1)//移除最大值
		{
			head1 = head1->next;
		}
		else
		{
			p = head1;
			while(p->next != pmin)
			{
				p = p->next;
			}
			p->next = pmin->next;
		}
		/*插入最大值*/
		pmin->next = NULL;
		pmin->next = newhead;
		newhead = pmin;		
	}
	head->next = newhead;
	/*展示排序后的链表*/
	p = head->next;
	printf("总成绩从高到底开始显示!\n");
	while(p != NULL)
	{
		printf("姓名:%s\t总分:%.2f\t密码:%s\t学号:%d\t性别:%s\t出生:%s\t数学分数:%.2f\t语文分数:%.2f\t英语分数%.2f\n",p->name,(p->math+p->chinese+p->english),p->ser,p->num,\
		p->sex,p->bir,p->math,p->chinese,p->english);
		p = p->next;
	}
	return;
}

小结:

其实很容易可以发现,老师分支的很多操作跟管理员分支差不多,我们只需要让两者很好的联系起来就行了。这边主要就是把握程序的一个整体框架,至于具体每个分支所需要的知识和难点就不做详细介绍了。

四、学生分支函数

学生这边其实就比较简单了,比起前面的老师分支,我们只需要很短的时间就可以做出来。


#include "stu.h"
//修改学生密码
void mod_stu_ser(STU*p)
{
	printf("请输入新的密码:");
	scanf("%s",p->ser);
	while(getchar() != '\n');
	printf("修改成功!\n");
	return ;
}
//查找学生信息
STU*search_stu(STU*head,int num)
{
	STU *ps = NULL,*p = NULL;
	p = head->next;
	while(p != NULL)
	{
		if(p->num == num)
		{
			ps = p;
		}
		p = p->next;
	}
	if(ps == NULL)
	{
		printf("无该学生信息!\n");
	}
	return ps;
}
void stu_info()
{
	STU*head = NULL;
	head = create_stu_node();
	head = read_stu();
	STU*s = NULL;
	int flag = 1;
	int num;
	char ser[20];
	while(flag)
	{
		printf("——————————————————————————\n");
		printf("   欢迎来到学生登陆页面!\n");
		printf("请输入您的学号:");
		scanf("%d",&num);
		while(getchar() != '\n');
		printf("请输入您的密码:");
		scanf("%s",ser);
		while(getchar() != '\n');
		printf("登陆中...\n");
		printf("——————————————————————————\n");
		s = search_stu(head,num);
		if(NULL == s)
		{
			printf("登陆失败!\n");
			return;
		}
		if(s->num == num && strcmp(s->ser,ser)==0)
		{
			printf("登陆成功!\n");
			break;
		}
		else
		{
			printf("信息有误,请核实学号和密码!\n");
			printf("———————————————————————————————————————\n");
			return;
		}
	}
		int x = 1,set;
		while(x)
		{
			printf("————————————————————————————————\n");
			printf("|        学生功能菜单!         |\n");
			printf("————————————————————————————————\n");
			printf("|1、修改密码                   |\n");
			printf("————————————————————————————————\n");
			printf("|2、查阅信息                   |\n");
			printf("————————————————————————————————\n");
			printf("|0、返回上一层                 |\n");
			printf("————————————————————————————————\n");
			printf("|请输入您的选择                |\n");
			printf("————————————————————————————————\n");
			scanf("%d",&set);
			while(getchar() != '\n');
			switch(set)
			{
				case 1:mod_stu_ser(s);break;
				case 0:x = 0;break;
				case 2:
						printf("姓名:%s\t密码:%s\t学号:%d\t性别:%s\t出生:%s\t数学分数:%.2f\t语文分数:%.2f\t英语分数%.2f\n",s->name,s->ser,s->num,\
						s->sex,s->bir,s->math,s->chinese,s->english);break;
				default:printf("还没有这个功能!\n");break;
			}
		}

	write_stu(head);
	return;
}


4.1、需要用到的头文件如下

#pragma once
#include "teacher.h"
void stu_info();

到这里差不多就结束了各个分支的函数编写,只需要再来一个主函数,把他们连起来

五、主函数连接

#include <stdio.h>
#include "teacher.h"
#include "adm.h"
#include "stu.h"
int main(){
	int set,flag = 1;
	while(flag)
	{

		printf("————————————————————————————————————\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("请输入您的身份选择:");
		scanf("%d",&set);
		while(getchar() != '\n');
		switch(set)
		{
			case 1:adm_info();break;
			case 2:teacher_info();break;
			case 3:stu_info();break;
			case 0:flag = 0;printf("成功退出系统!\n");break;
			default:printf("无此选项!\n");break;
		
		}
	}
    return 0;
}

总结

通过以上步骤,我们就实现了开头想要实现的功能,这只能算是一个很粗糙的小项目了,还有很多可以完善的地方。总的来说,有了这种基本的思路,想增加什么功能,往里面有序的添加就好。文章来源地址https://www.toymoban.com/news/detail-480380.html

到了这里,关于如何用C语言写一个简单的教务管理系统的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java教务管理系统

    本项目采用MVC框架,对代码分层,分为Dao,Pojo,Service,Utils,View, swing的视图设计上我是参考了其他人的设置,功能上全由个人编写,第一版的实现可能会由有很多不足的地方,欢迎大家评论区讨论。 登陆功能,图片大家可以随意更换 首页 课程查询 选课系统 成绩查询 通知

    2024年02月12日
    浏览(34)
  • java实现教务管理系统

    git地址 :https://gitee.com/myshort-term/school-management         开发教务管理系统程序,设计了ems(EMSApp)、dao(AssignmentDAO、CourseDAO、DeptDAO、ScoreDAO、UserDAO、EmailDAO)、domain(Assignment、Course、Department、Score、User)、test(MySQLDemo)和util(AssignmentInput、CourseInput、DataInput、DBHelper、

    2024年02月03日
    浏览(30)
  • 教务信息管理系统的设计与实现

    目 录 第一章 绪论 1 1.1 选题背景及意义 1 1.2国内外研究现状 1 1.2.1国际教育信息化现状 1 1.2.2国内教育信息化现状 2 1.3研究主要内容 2 第二章 开发环境和相关技术简介 4 2.1 开发环境 4 2.2 相关技术 4 2.2.1 MVC简介 4 2.2.2 Struts2简介 6 2.2.3 JSP简介 7 2.2.4 CSS简介 8 2.2.5 Spring简介 9 2.2

    2024年01月19日
    浏览(38)
  • 基于web的教务管理系统-课程设计

    教务系统已成为高校不可缺的系统,它可以帮人相关人员从繁琐的事务脱离出来,提高高中效率,但是真正的想实现一个教务管理系统,是很难的,它涉及的领域很广,所以本文的教务管理系统只实现了教务中的排课(手动)、成绩录入模块,主要分为以下三大角色:管理员(教

    2024年02月11日
    浏览(36)
  • 用Vue写教务系统学生管理

    2024年02月05日
    浏览(29)
  • 基于java中学教务管理系统设计与实现

    摘要 随着现代技术的不断发展,计算机已经深度的应用到了当下的各个行业之中,教育行业也不例外。计算机对教育行业中的教务管理等内容的帮助,使得教职工从传统的手工办公像计算机辅助阶段迈进,并且实现了非常好的发展。现在的学校在面对日益增长的学生人数,在

    2024年02月15日
    浏览(32)
  • 基于SSM的学校教务管理系统——LW模板

    在当前信息技术飞速发展的潮流下,越来越多的行业信息保存方式开始转换为互联网,以前在纸质化的信息保存方式下,信息易丢失,不易查找等重大缺点显而易见,但是在当前的技术下,计算机存储已经是各行各业都认可并都支持爱戴的一种数据保存方式。例如,学校使用

    2024年02月11日
    浏览(57)
  • PHP版学校教务管理系统源码带文字安装教程

    PHP版学校教务管理系统源码带文字安装教程 运行环境 服务器宝塔面板 PHP 7.0 Mysql 5.5及以上版本 Linux Centos7以上 系统介绍: 后台权限控制:支持多个管理员,学生管理,学生成绩,教师管理,文章管理, 站点管理,网站布局自动化,多导航模式,友情链接,站点工具。 前台

    2024年02月02日
    浏览(36)
  • 基于SSM框架开发的教务管理系统(毕业设计,期末设计)

    目录 🍬1 前言 1.1 项目所需要的知识 1.2 开发项目的环境和工具 🍬2 系统结构 2.1系统流程图(E-R图) 2.2配置pom.xml 🍬3 程序设计及运行 3.1添加课程信息 (1)功能描述 (2)实现代码 (3)实现截图 3.2学生已修课程 (1)功能描述 (2)实现代码 (3)实现截图 3.3添加教师信

    2024年02月08日
    浏览(55)
  • Java项目:基于JavaWeb的教务管理系统的设计与实现

    作者主页:夜未央5788  简介:Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 本项目为基于WEB的教务管理系统。 主要系统功能包括: 学生管理:显示所有学生、添加学生; 课程管理:显示所有课程、添加课程; 学院管理:显示所有学院、添加学

    2024年02月11日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包