c程设计课作业——学生管理系统
功能比较普通,借鉴了一下别人的思路写的。
stumanage.h
#ifndef _STUMANAGE_H
#define _STUMANAGE_H
#define FILENAME "student.dat" //学生信息保存文件的文件名
typedef enum { MAN, WOMAN } SEX;//枚举类型性别
typedef struct Stu
{
int num; //学生的学号
char name[20]; //学生的姓名
SEX sex; //学生的性别
int age; //学生的年龄
int score[6]; //成绩
//数组保存的成绩依次为语文、数学、英语、思品、科学及总成绩
struct Stu *next;//下一个节点的指针
}StuN, *StuP;
//1.主运行函数
void MainRun();
//2.选项页面函数
void ShowOptionPage();
//3.用户选择获取函数
int GetUserOption();
//4.头结点创建函数
StuP SheadCreate();
//5.学生信息节点创建函数
StuP CreateStuNode(StuP Head);
//6.学生信息节点链接函数
int AddStuNode(StuP snode, StuP Head);
//7.指定编号学生节点前置节点返回函数
StuP GetPrevNode(int num, StuP Head);
//8.所有学生信息显示函数
void ShowAllStu(StuP Head);
//9.学生信息排序函数
void StuSort(StuP Head);
//10.文件读取学生信息函数
void LoadFile(StuP Head);
//11.成绩计算函数
void Sum(int *arr);
//12.指定学生信息显示函数
void ShowOneStu(StuP Head);
//13.学生信息数量显示函数
int ShowStuNum(StuP Head);
//14.学生信息修改函数(参数为欲修改的学生的编号 )
void StuInfoChange(int num, StuP Head);
//15.用户选择获取函数
int Question(const char *p);
//16.用户输入学号获取函数
int GetInputNum();
//17.删除指定学生信息函数
void DelStuNode(int num, StuP Head);
//18.删除所有学生信息函数
void DelAllNode(StuP Head);
//19.学生信息保存到文件函数
void SaveFile(StuP Head);
#endif // !_STUMANAGE_H
function.c
#include<stdio.h>
#include<stdlib.h>
#include"stumanage.h"
//1.主运行函数
void MainRun() {
int flag = 1;
//创建链表空头节点
StuP Head = SheadCreate();
while (flag)
{
switch (GetUserOption())
{
case 0:
flag = 0;
break;
case 1:
printf("你选择了菜单1\n");
AddStuNode(CreateStuNode(Head), Head);
break;
case 2:
printf("你选择了菜单2\n");
DelStuNode(GetInputNum(), Head);
break;
case 3:
printf("你选择了菜单3\n");
ShowOneStu(Head);
break;
case 4:
printf("你选择了菜单4\n");
StuInfoChange(GetInputNum(), Head);
break;
case 5:
printf("你选择了菜单5\n");
DelAllNode(Head);
break;
case 6:
printf("你选择了菜单6\n");
ShowAllStu(Head);
break;
case 7:
printf("你选择了菜单7\n");
ShowStuNum(Head);
break;
case 8:
printf("你选择了菜单8\n");
LoadFile(Head);
break;
case 9:
printf("你选择了菜单9\n");
SaveFile(Head);
break;
case 10:
printf("你选择了菜单10\n");
StuSort(Head);
break;
}
system("pause");
}
}
//2.菜单显示函数
void ShowOptionPage()
{
system("cls");//清屏
printf("-------------------------------------------学生管理系统--------------------------------------------\n");
printf("\n\t\t1.添加学生信息 2.删除某个学生信息 3.显示某个学生信息\n");
printf("\t\t4.修改学生信息 5.删除所有学生信息 6.显示所有学生信息\n");
printf("\t\t7.显示信息数量 8.读取文件学生信息 9.保存学生信息至文件\n");
printf("\t\t10.学生信息排序 0.退出系统\n");
printf("\n---------------------------------------------------------------------------------------------------\n");
}
//3.用户选择获取函数
int GetUserOption()
{
int num;//保存用户选择的选项编号
ShowOptionPage();
printf("请选择选项(0 ~ 10):");
while (1 != scanf("%d", &num) || num < 0 || num > 10)
{
ShowOptionPage();
printf("选择选项错误,请重新选择(0 ~ 10):");
}
return num;
}
//4.头结点创建函数
StuP SheadCreate()
{
StuP _Head;
_Head = (StuP)malloc(sizeof(StuN));
_Head->next = NULL;
return _Head;
}
//5.学生信息节点创建函数
StuP CreateStuNode(StuP Head)
{
int sex;
int i;
char classes[][5] = { "语文","数学","英语","思品","科学" };
//在申请内存空间,存储学生信息
StuP snode = (StuP)malloc(sizeof(StuN));
//空间申请失败情况
if (!snode)
{
printf("申请内存空间失败!\n");
return NULL;
}
//空间申请正常情况
//1.学号输入
printf("请输入学生的学号(整型):");
scanf("%d", &snode->num);
while (GetPrevNode(snode->num, Head))
{
printf("学生编号输入错误或已经存在,请重新输入学生的编号(整型):");
scanf("%d", &snode->num);
}
//2.姓名输入
printf("请输入学生的姓名(小于20字符):");
scanf("%20s", snode->name);
//3.性别输入
printf("请选择学生的性别(0.男 1.女):");
scanf("%d", &sex);
while (sex < 0 || sex > 1)
{
printf("性别选择错误,请重新选择学生的性别(0.男 1.女):");
scanf("%d", &sex);
}
if (sex == 0)
snode->sex = MAN;
else
snode->sex = WOMAN;
printf("请输入学生的年龄(7 ~ 12):");
scanf("%d", &snode->age);
while (snode->age < 7 || snode->age > 12)
{
printf("年龄输入错误!请重新输入学生的年龄(7 ~ 12):");
scanf("%d", &snode->age);
}
//4.成绩输入及计算总成绩
for (i = 0; i < 5; i++) {
printf("请输入该学生的%s成绩:\n", &classes[i]);
scanf("%d", &snode->score[i]);
while (snode->score[i] < 0 || snode->score[i]>100)
{
printf("输入的成绩有误(成绩范围:0 ~ 100)!\n");
scanf("%d", &snode->score[i]);
}
}
Sum(snode->score);
printf("该学生总成绩为:%d\n", snode->score[5]);
snode->next = NULL;
return snode;
}
//6.把学生信息节点加入到链表中
int AddStuNode(StuP snode, StuP Head)
{
StuP p = Head;
//传入节点为空
if (!snode)
{
return 0;
}
//判断该学生信息是否已经存在
if (GetPrevNode(snode->num, Head))
{
printf("编号为%d的学生信息已经存在!\n", snode->num);
free(snode);//释放该节点内存空间
return 0;
}
//找到当前链表的最后一个节点
while (p->next)
p = p->next;
//把新节点加入到最后节点后面
p->next = snode;
snode->next = NULL;
return 1;
}
//7.指定编号学生节点前置节点返回函数
StuP GetPrevNode(int num, StuP Head)
{
StuP snode = Head;
while (snode->next)
{
if (snode->next->num == num)
return snode;
snode = snode->next;
}
return NULL;
}
//8.所有学生信息显示函数
void ShowAllStu(StuP Head)
{
int i;
StuP snode = Head->next;
printf("---------------------------------------------------------------------------------------------------\n");
printf(" 编号 姓名 性别 年龄 语文 数学 英语 思品 科学 总分\n");
printf("---------------------------------------------------------------------------------------------------\n");
while (snode)
{
printf(" %-8d ", snode->num);
printf("%-20s", snode->name);
printf("%-6s", snode->sex == MAN ? "男" : "女");
printf("%4d", snode->age);
for (i = 0; i < 5; i++) {
printf("%9d", snode->score[i]);
}
printf("%9d\n", snode->score[i]);
snode = snode->next;//让指针指向下一个节点
}
printf("---------------------------------------------------------------------------------------------------\n");
}
//9.学生信息排序函数
void StuSort(StuP Head)
{
if (!(Head->next) || !(Head->next->next)) {
printf("还未输入学生信息,请补充!\n");
return;
}
if (!(Head->next->next)) {
printf("学生信息少于三条无法进行排序,请补充!\n");
return;
}
StuP _Head;
StuP _Tail;
StuP _Pre;
StuP _Cur;
StuP _Next;
StuP _Temp;
_Head = Head;
_Tail = NULL;
int Type;
printf("请输入排序标准对应的选项:0、语文 1、数学 2、英语 3、思品 4、科学 5、总分\n");
scanf("%d", &Type);
while (Type<0 || Type>5) {
printf("输入错误,请重新输入!\n");
scanf("%d", &Type);
}
//冒泡排序
while (_Head->next != _Tail) {
for (_Pre = _Head, _Cur = _Pre->next, _Next = _Cur->next; _Next != _Tail; _Pre = _Pre->next, _Cur = _Cur->next, _Next = _Next->next)
{
if (_Cur->score[Type] < _Next->score[Type])
{
_Cur->next = _Next->next;
_Pre->next = _Next;
_Next->next = _Cur;
_Temp = _Next;
_Next = _Cur;
_Cur = _Temp;
}
}
_Tail = _Cur;
}
printf("排序完成,请显示所有所有学生信息以查看。\n");
}
//10.文件读取学生信息函数
void LoadFile(StuP Head)
{
int i, num = 0, re = 0;
FILE *fp;
StuP snode;
printf("提示:从文件中读取学生信息会询问是否清空当前学生信息。\n");
if ((fp = fopen(FILENAME, "rb")) == NULL)
{
printf("文件还没有创建,请输入学生信息并保存!\n");
return;
}
//删除之前的所有学生信息,然后从文件中读取
DelAllNode(Head);
//获取学生信息的数量
fread(&num, 1, sizeof num, fp);
for (i = 0; i < num; i++)
{
snode = (StuP)malloc(sizeof(StuN));
fread(snode, 1, sizeof(StuN), fp);
AddStuNode(snode, Head);
}
fclose(fp);
printf("文件读取完毕!新增学生信息%d条。\n", num);
}
//11.成绩计算函数
void Sum(int *arr) {
int i;
arr[5] = 0;
for (i = 0; i < 5; i++) {
arr[5] += arr[i];
}
}
//12.指定学生信息显示函数
void ShowOneStu(StuP Head) {
int i;
StuP p;
int numb;
printf("请输入想查找学生的编号:");
scanf("%d", &numb);
p = GetPrevNode(numb, Head);
if (!p)
{
printf("该学生不存在!");
}
else {
p = p->next;
printf("---------------------------------------------------------------------------------------------------\n");
printf(" 编号 姓名 性别 年龄 语文 数学 英语 思品 科学 总分\n");
printf("---------------------------------------------------------------------------------------------------\n");
printf(" %-8d ", p->num);
printf("%-20s", p->name);
printf("%-6s", p->sex == MAN ? "男" : "女");
printf("%4d", p->age);
for (i = 0; i < 5; i++) {
printf("%9d", p->score[i]);
}
printf("%9d\n", p->score[i]);
printf("---------------------------------------------------------------------------------------------------\n");
}
}
//13.学生信息数量显示函数
int ShowStuNum(StuP Head)
{
int num = 0;
StuP p;
for (p = Head; p->next; p = p->next) {
num++;
}
printf("\n当前共有%d位学生信息。\n", num);
return num;
}
//14.学生信息修改函数(参数为欲修改的学生的编号)
void StuInfoChange(int num, StuP Head)
{
int select;
int sex;
int clsel;
int score;
char classes[][5] = { "语文","数学","英语","思品","科学" };
//获取要修改的学生节点的上一个节点
StuP p = GetPrevNode(num, Head);
if (!p)
{
printf("没有编号为%d的学生信息。\n", num);
return;
}
//将要指针指向所要修改的学生节点
p = p->next;
printf("请输入你想要修改的该学生的信息:1、姓名 2、性别 3、年龄 4、成绩\n");
scanf("%d", &select);
while (select < 1 || select>4) {
printf("输入错误,请重新输入!\n");
scanf("%d", &select);
}
switch (select)
{
case 1://姓名
{
printf("当前学生的姓名为%s,", p->name);
if (Question("确定要修改吗?"))
{
printf("请输入学生的姓名(小于20字符):");
scanf("%20s", p->name);
printf("修改完毕!\n");
}
break;
}
case 2://性别
{
printf("当前学生的性别为%s,", p->sex == MAN ? "男" : "女");
if (Question("确定要修改吗?"))
{
printf("请输入学生的性别(0.男 1.女):");
scanf("%d", &sex);
while (sex < 0 || sex > 1)
{
printf("输入错误,请重新输入学生的性别(0.男 1.女):");
scanf("%d", &sex);
}
if (sex == 0)
p->sex = MAN;
else
p->sex = WOMAN;
printf("修改完毕!\n");
}
break;
}
case 3://年龄
{
printf("当前学生的年龄为%d,", p->age);
if (Question("确定要修改吗?"))
{
printf("请输入学生的年龄(7 ~ 12):");
scanf("%d", &p->age);
while (p->age < 7 || p->age > 12)
{
printf("年龄输入错误!请重新输入学生的年龄(7 ~ 12):");
scanf("%d", &p->age);
}
printf("修改完毕!\n");
}
break;
}
case 4://成绩
{
printf("请输入你想要修改科目成绩的对应选项:0、语文 1、数学 2、英语 3、思品 4、科学\n");
scanf("%d", &clsel);
while (clsel < 0 || clsel>4) {
printf("输入错误,请重新输入!");
scanf("%d", &clsel);
}
printf("当前学生的%s成绩为%d,", classes[clsel], p->score[clsel]);
if (Question("确定要修改吗?"))
{
printf("请输入学生的%s成绩:", classes[clsel]);
scanf("%d", &score);
while (score < 0 || score > 100)
{
printf("输入错误!请重新输入学生的成绩(0 ~ 100):");
scanf("%d", &score);
}
p->score[clsel] = score;
Sum(p->score);
printf("修改完毕!\n");
printf("修改后该学生总成绩为:%d\n", p->score[5]);
}
break;
}
}
}
//15.获取用户的选择
int Question(const char *p)
{
char answer;
printf("%s请选择(y or n):", p);
scanf(" %c", &answer);
while (answer != 'y' && answer != 'n')
{
printf("输入错误!%s请重新选择(y or n):", p);
scanf(" %c", &answer);
}
if (answer == 'y')
return 1;
else
return 0;
}
//16.用户输入学编号获取函数
int GetInputNum()
{
int num;
printf("请输入学生的编号:");
scanf("%d", &num);
return num;
}
//17.删除指定学生系信息函数
void DelStuNode(int num, StuP Head)
{
StuP p, q;
if (p = GetPrevNode(num, Head))
{
if (!Question("确定要删除该学生信息吗?"))
{
return;
}
q = p->next;
p->next = q->next;
free(q);
printf("删除了编号为%d的学生信息。\n", num);
}
else
{
printf("没有找到编号为%d的学生信息。\n", num);
}
}
//18.删除所有学生信息
void DelAllNode(StuP Head)
{
StuP p = Head->next, t;
int sum = 0;
if (!Question("确定要删除当前所有的学生信息吗?"))
{
return;
}
while (p)
{
t = p;
p = p->next;
free(t);
sum++;
}
printf("共删除了%d位学生信息。\n", sum);
Head->next = NULL;
}
//19.学生信息保存到文件函数
void SaveFile(StuP Head)
{
FILE *fp = fopen(FILENAME, "wb");
StuP p = Head;
int i = 0, sum = ShowStuNum(Head);
if (!fp)
{
printf("打开待写入的文件失败!\n");
return;
}
if (!Question("确定要将当前学生信息保存到文件中吗?"))
{
fclose(fp);
return;
}
//把学生信息的数量先写入到文件头
fwrite(&sum, 1, sizeof(sum), fp);
while (p->next)
{
//把每位学生信息写入文件
fwrite(p->next, 1, sizeof(StuN), fp);
i++;
p = p->next;
}
fclose(fp);
printf("成功的写入了%d条学生信息。\n", sum);
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include"stumanage.h"
int main()
{
MainRun();
return 0;
}