学生成绩管理系统
前言
该学生管理系统利用C语言管理学生成绩,高效处理学生信息,主要功能为录入、打印学生信息,对学生信息进行保存和读取,统计学生人数,查找学生信息,修改和删除学生信息等。
一、功能架构图
二、模块功能说明
//定义一个学生结构体
typedef struct tagStudent {
char Name[20]; //姓名
char Sex[4]; //性别
int Age; //年龄
int Num; //学号
int Score; //成绩
}Student;
//链表
//节点
typedef struct tagNode
{
Student stu; //学生信息
struct tagNode* pNext; //指向下一个节点
}Node;
//创建头节点
Node* g_pHead = NULL; //指向头节点
1.菜单
调用菜单函数Menu()形成操作界面,根据提示序号选择操作程序
代码如下:
void Menu() {
printf("*************************************************\n");
printf("*\t欢迎使用高校学生成绩管理系统V1.0\t*\n");
printf("*\t\t请选择功能\t\t\t*\n");
printf("*************************************************\n");
printf("*\t\t1.录入学生信息\t\t\t*\n");
printf("*\t\t2.打印学生信息\t\t\t*\n");
printf("*\t\t3.保存学生信息\t\t\t*\n");
printf("*\t\t4.读取学生信息\t\t\t*\n");
printf("*\t\t5.统计所有学生人数\t\t*\n");
printf("*\t\t6.查找学生信息\t\t\t*\n");
printf("*\t\t7.修改学生信息\t\t\t*\n");
printf("*\t\t8.删除学生信息\t\t\t*\n");
printf("*\t\t0.退出系统\t\t\t*\n");
printf("*************************************************\n");
}
2.录入学生信息
创建单链表,输入学生信息
代码如下:
void InputStudent() {
//创建一个结点,分配内存
Node* pNewNode = (Node*)malloc(sizeof(Node));
//指针下一个指向空
pNewNode->pNext = NULL;
//查找链表的尾结点
Node* p = g_pHead;
while (g_pHead != NULL && p->pNext != NULL)
{
p = p->pNext;
}
//把节点插到链表的尾节点
if (g_pHead == NULL) {
g_pHead = pNewNode;
}
else {
p->pNext = pNewNode;
}
//录入学生信息
printf("请输入学生姓名:\n");
scanf("%s", pNewNode->stu.Name, sizeof(pNewNode->stu.Name));
printf("请输入性别:\n");
scanf("%s", pNewNode->stu.Sex, sizeof(pNewNode->stu.Sex));
printf("请输入学生年龄:\n");
scanf("%d", &pNewNode->stu.Age);
printf("请输入学号:\n");
scanf("%d", &pNewNode->stu.Num);
printf("请输入成绩:\n");
scanf("%d", &pNewNode->stu.Score);
printf("学生信息录入成功。\n\n");
system("pause");
system("cls");
}
3.打印学生信息
遍历链表,从头结点开始,顺着指针依次访问各个结点,取出各个结点的数据,直到最后一个结点
(内部的pNext指针值为NULL)
void PrintStudent() {
system("cls");
//遍历链表
Node* p = g_pHead;
if (p == NULL) {
printf("系统中暂无学生信息,请录入后再来打印查看。\n\n");
}
else {
printf("*********************************************************************************\n");
printf("*\t\t\t欢迎使用高校学生成绩管理系统V1.0\t\t\t*\n");
printf("*********************************************************************************\n");
printf("*\t学号\t*\t姓名\t*\t性别\t*\t年龄\t*\t成绩\t*\n");
printf("*********************************************************************************\n");
while (p != NULL)
{
printf("*\t%d\t*\t%s\t*\t%s\t*\t%d\t*\t%d\t*\n",
p->stu.Num,
p->stu.Name,
p->stu.Sex,
p->stu.Age,
p->stu.Score
);
//下一个节点
p = p->pNext;
printf("*********************************************************************************\n");
}
}
system("pause");
system("cls");
}
4.保存学生信息
将学生信息存储到一个文件中
void SaveStudent() {
//打开文件
FILE* pFile;
pFile = fopen(".\\stuinfo.dat", "w");
if (pFile == NULL) {
printf("打开文件失败。\n");
return;
}
//写入数据
Node* p = g_pHead;
while (p != NULL)
{
fwrite(&p->stu, sizeof(Node), 1, pFile);
p = p->pNext;
}
//关闭文件
fclose(pFile);
printf("数据保存成功。\n");
system("pause");
system("cls");
}
5.读取学生信息
void ReadStudent(){
system("cls");
//打开文件
FILE* pFile;
pFile = fopen(".\\stuinfo.dat", "r");
if (pFile == NULL) {
printf("打开文件失败。\n");
return;
}
//创建一个结点,分配内存
Node* p = (Node*)malloc(sizeof(Node));
p->pNext = NULL;
//重新建立链表
g_pHead = p;
//逐个单词读入文本内容
char str[200];
int i = 0;
while (fscanf(pFile, "%s", str) != EOF) { //读文件
//单词不是*或者空时,进行赋值
if (strcmp(str, "*") && str != NULL) {
switch (i)
{
case 0:
p->stu.Num = atoi(str);
break;
case 1:
strcpy(p->stu.Name, str);
break;
case 2:
strcpy(p->stu.Sex, str);
break;
case 3:
p->stu.Age = atoi(str);
break;
case 4:
p->stu.Score = atoi(str);
break;
default:
Node* pNewNode = (Node*)malloc(sizeof(Node));
pNewNode->pNext = NULL;
p->pNext = pNewNode;
p = pNewNode;
p->stu.Num = atoi(str);
i = 0;
break;
}
i++;
}
}
//打印读取结果
PrintStudent();
}
6.统计所有学生人数
遍历链表,统计链表结点个数
void CountStudent() {
int countStu = 0;
//遍历链表
Node* p = g_pHead;
while (p != NULL)
{
countStu++;
p = p->pNext;
}
printf("学生总人数:%d\n\n", countStu);
system("pause");
system("cls");
}
7.查找学生信息
提示用户输入需查找学生的学号,进行链表遍历,如果该信息存在,输出学生信息,否则提出提示信息
void FindStudent() {
system("cls");
//利用学号查询
int stuNum;
printf("请输入查找学生学号:");
scanf("%d", &stuNum);
//遍历链表查找,查找到后进行信息显示
Node* p = g_pHead;
//对表头进行展示一次
bool isShowHead = false;
//记录是否有找到该学号的学生信息
bool isFindStu = false;
while (p != NULL)
{
if (stuNum == p->stu.Num) {
if (!isShowHead) {
printf("*********************************************************************************\n");
printf("*\t学号\t*\t姓名\t*\t性别\t*\t年龄\t*\t成绩\t*\n");
printf("*********************************************************************************\n");
isShowHead = true;
}
printf("*\t%d\t*\t%s\t*\t%s\t*\t%d\t*\t%d\t*\n",
p->stu.Num,
p->stu.Name,
p->stu.Sex,
p->stu.Age,
p->stu.Score
);
isFindStu = true;
printf("*********************************************************************************\n");
}
p = p->pNext;
}
if (!isFindStu) {
printf("学号输入有误,系统中暂无该学生信息。\n\n");
}
system("pause");
system("cls");
}
8.修改学生信息
提示用户输入要进行修改操作的学号,如果存在,进行各项信息的修改,否则输出提示信息
void ChangeStudent(){
//利用学号查询
int stuNum;
printf("请输入修改学生的学号:");
scanf("%d", &stuNum);
//遍历链表查找,查找到后进行信息显示
Node* p = g_pHead;
//对表头进行展示一次
bool isShowHead = false;
//记录是否有找到该学号的学生信息
bool isFindStu = false;
while (p != NULL)
{
if (stuNum == p->stu.Num) {
if (!isShowHead) {
printf("*********************************************************************************\n");
printf("*\t学号\t*\t姓名\t*\t性别\t*\t年龄\t*\t成绩\t*\n");
printf("*********************************************************************************\n");
isShowHead = true;
}
printf("*\t%d\t*\t%s\t*\t%s\t*\t%d\t*\t%d\t*\n",
p->stu.Num,
p->stu.Name,
p->stu.Sex,
p->stu.Age,
p->stu.Score
);
//修改学生信息
printf("请输入学生姓名:\n");
scanf("%s", p->stu.Name, sizeof(p->stu.Name));
printf("请输入性别:\n");
scanf("%s", p->stu.Sex, sizeof(p->stu.Sex));
printf("请输入学生年龄:\n");
scanf("%d", &p->stu.Age);
printf("请输入学号:\n");
scanf("%d", &p->stu.Num);
printf("请输入成绩:\n");
scanf("%d", &p->stu.Score);
isFindStu = true;
printf("*********************************************************************************\n");
printf("学生信息修改成功,请注意及时保存。\n\n");
}
p = p->pNext;
}
if (!isFindStu) {
printf("学号输入有误,系统中暂无该学生信息,无法进行修改。\n\n");
}
system("pause");
system("cls");
}
9.删除学生信息
提示用户输入要进行删除操作的学号,如果该学号存在,则将该学号所对应的学生信息删除,否则输出提示信息
void DeleteStudent() {
system("cls");
//利用学号查询
int stuNum;
printf("请输入删除学生的学号:");
scanf("%d", &stuNum);
//遍历链表查找,查找到后进行信息显示
Node* p = g_pHead;
//记录前一个节点,删除时方便操作
Node* beforeNode = g_pHead;
//对表头进行展示一次
bool isShowHead = false;
//记录是否有找到该学号的学生信息
bool isFindStu = false;
while (p != NULL)
{
if (stuNum == p->stu.Num) {
if (!isShowHead) {
printf("*********************************************************************************\n");
printf("*\t学号\t*\t姓名\t*\t性别\t*\t年龄\t*\t成绩\t*\n");
printf("*********************************************************************************\n");
isShowHead = true;
}
printf("*\t%d\t*\t%s\t*\t%s\t*\t%d\t*\t%d\t*\n",
p->stu.Num,
p->stu.Name,
p->stu.Sex,
p->stu.Age,
p->stu.Score
);
isFindStu = true;
printf("*********************************************************************************\n");
//删除节点为头节点
if (p == g_pHead) {
g_pHead = p->pNext;
}
//删除节点为尾节点
else if (p->pNext == NULL) {
p = beforeNode;
p->pNext = NULL;
}
//删除节点为中间节点
else {
beforeNode->pNext = p->pNext;
}
printf("删除成功,请记得保存。\n\n");
}
beforeNode = p;
p = p->pNext;
}
if (!isFindStu) {
printf("学号输入有误,系统中暂无该学生信息,无法进行删除操作。\n\n");
}
system("pause");
system("cls");
}
总结
通过这次实验,更好地掌握和巩固了C语言编写的相关知识和技巧,特别是函数、指针、结构体、链表等功能。从头开始编写一个简洁明了、结构清晰的学生管理系统,需要花费大量的时间积累、沉淀。作为一个新手,还没有实际经验,有很多功能没有完成,以后会在此基础上进行改进。