学生成绩管理系统
项目分析
在学生成绩管理系统中,我们将实现7大功能,分别是添加记录、显示记录、修改记录、删除记录、查找记录、排序记录以及退出系统。
需求分析
- 添加记录
这个功能主要是添加学生的信息,当用户在功能菜单中选择数字1时,会进入添加记录模块,提示用户输入学生的学号、姓名、数学成绩、语文成绩。当用户输入完毕后,会提示用户是否继续添加,Y表示继续,N表示返回。需要注意的是,在添加学号时不能重复,如果输入重复的学号就会提示此学号存在。
- 显示记录
这个功能主要是显示已存入的学生信息,当用户在功能菜单中选择数字2时,会进入显示记录模块,并向控制台输出录入的所有学生的学号、姓名、数学成绩、语文成绩和成绩总和。
- 修改记录
这个功能主要是修改学生信息,当用户在功能菜单中选择数字3时,会进入修改记录模块,输入要修改的学生姓名,当用户输入了已录入的学生姓名后,如果学生信息存在即可修改除学号以外的其他信息,否则输出该学生不存在。
- 删除记录
这个功能主要是删除已录入的学生信息,当用户在功能菜单中选择数字4时,会进入删除记录模块,对学生学号进行判断,如果学号存在即可删除该生的所有信息,否则输出没有找到该生的记录。
- 查找记录
这个功能主要是提示查找某个学生信息,当用户在功能菜单中输入数字5时,会进入查找记录模块,在该模块中输入查找的学生姓名,如果该学生存在则输出该学生的全部信息,否则输出没有找到该生的记录。
- 排序记录
这个功能主要是对学生总成绩进行排序,当用户在功能菜单中输入数字6时,会进入排序记录模块,该模块会输出所有学生的信息,并按总成绩由高到低进行排序。
- 对出系统
这个功能主要是退出系统,当在功能菜单中输入数字0即可退出系统,并输出程序结束。
数据设计
完成系统的需求分析后,就需要根据需求设计项目中的数据。由于学生成绩管理系统中多次涉及到学生信息及其成绩信息的操作,因此根据学生成绩管理系统的需求,设计的学生数据如表所示
变量声明 | 功能描述 |
---|---|
int id | 学号 |
char name[8] | 姓名 |
int chinese | 语文成绩 |
int math | 数学成绩 |
int sum | 总成绩 |
从表中可以看出,学生的数据类型各不相同,为了便于统一管理这些学生数据,可以使用结构体类型来声明这些数据,具体代码如下所示:
struct student //学生记录
{
int id; //学号
char name[8]; //姓名
int chinese; //语文成绩
int math; //数学成绩
int sum; //总分
};
在开发项目时,除了要针对项目中的数据进行设计,还需要根据系统的需求,规划项目中需要定义的函数,接下来通过下表来列举本项目中所需使用的所有函数及其功能。
函数声明 | 功能描述 |
---|---|
void menu(); | 显示功能菜单 |
void add(struct student stu[]); | 添加学生信息 |
void show(struct student stu[], int i); | 显示某个学生信息 |
void showAll(struct student stu[]); | 显示所有学生信息 |
void modify(struct student stu[]); | 修改某个学生信息 |
void del(struct student stu[]); | 删除某个学生信息 |
void search(struct student stu[]); | 查询某个学生信息 |
void sort(struct student stu[]); | 对学生成绩进行排序 |
项目实现
预处理实现
student.h
#ifndef STUDENT //先测试STUDENT是否被宏定义过,避免重新使用
#define STUDENT //定义STUDENT
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define HH printf("%-10s%-10s%-10s%-10s%-10s\n","学号","姓名","语文","数学","总分")
struct student //学生记录
{
int id; //学号
char name[8]; //姓名
int chinese; //语文成绩
int math; //数学成绩
int sum; //总分
};
static int n; //记录学生信息条数
void menu();
void add(struct student stu[]); //函数声明
void show(struct student stu[], int i);
void showAll(struct student stu[]);
void modify(struct student stu[]);
void del(struct student stu[]);
void search(struct student stu[]);
void sort(struct student stu[]); //函数声明
#endif //结束条件编译
功能函数实现
student.c
#define _CRT_SECURE_NO_WARNINGS
#include "Student.h"
void menu()
{
system("cls");//清空屏幕
printf("\n");
printf("\t\t --------------学生成绩管理系统--------------\n");
printf("\t\t︱\t\t 1 添加记录 ︱\n");
printf("\t\t︱\t\t 2 显示记录 ︱\n");
printf("\t\t︱\t\t 3 修改记录 ︱\n");
printf("\t\t︱\t\t 4 删除记录 ︱\n");
printf("\t\t︱\t\t 5 查找记录 ︱\n");
printf("\t\t︱\t\t 6 排序记录 ︱\n");
printf("\t\t︱\t\t 0 退出系统 ︱\n");
printf("\t\t -----------------------------------------\n");
printf("\t\t请选择(0-6):");
}
void add(struct student stu[])
{
int i, id = 0; //i作为循环变量,id用来保存新学号
char quit; //保存是否退出的选择
do
{
printf("学号:");
scanf("%d", &id);
for (i = 0; i < n; i++)
{
if (id == stu[i].id) //假如新学号等于数组中某生的学号
{
printf("此学号存在!\n");
return;
}
}
stu[i].id = id;
printf("姓名:");
scanf("%s", &stu[i].name);
printf("语文:");
scanf("%d", &stu[i].chinese);
printf("数学:");
scanf("%d", &stu[i].math);
stu[i].sum = stu[i].chinese + stu[i].math; //计算出总成绩
n++; //记录条数加1
printf("是否继续添加?(Y/N)");
scanf("\t%c", &quit);
} while (quit != 'n'&&quit != 'N');
}
void show(struct student stu[], int i)
{
printf("%-10d", stu[i].id);
printf("%-10s", stu[i].name);
printf("%-10d", stu[i].chinese);
printf("%-10d", stu[i].math);
printf("%-10d\n", stu[i].sum);
}
void showAll(struct student stu[])
{
int i;
HH;
for (i = 0; i < n; i++)
{
show(stu, i);
}
}
void modify(struct student stu[])
{
char name[8], ch; //name用来保存姓名,ch用来保存是否退出的选择
int i;
printf("修改学生的记录。\n");
printf("请输入学生的姓名:");
scanf("%s", &name);
for (i = 0; i < n; i++)
{
if (strcmp(name, stu[i].name) == 0)
{
getchar(); //提取并丢掉回车键
printf("找到该生的记录,如下所示:\n");
HH; //显示记录的标题
show(stu, i); //显示数组stu中的第i条记录
printf("是否修改?(Y/N)\n");
scanf("%c", &ch);
if (ch == 'Y' || ch == 'y')
{
getchar(); //提取并丢掉回车键
printf("姓名:");
scanf("%s", &stu[i].name);
printf("语文:");
scanf("%d", &stu[i].chinese);
printf("数学:");
scanf("%d", &stu[i].math);
stu[i].sum = stu[i].chinese + stu[i].math; //计算出总成绩
printf("修改完毕。\n");
}
return;
}
}
printf("没有找到该生的记录。\n");
}
void del(struct student stu[])
{
int id, i;
char ch;
printf("删除学生的记录。\n");
printf("请输入学号:");
scanf("%d", &id);
for (i = 0; i < n; i++)
{
if (id == stu[i].id)
{
getchar();
printf("找到该生的记录,如下所示:\n");
HH; //显示记录的标题
show(stu, i); //显示数组stu中的第i条记录
printf("是否删除?(Y/N)\n");
scanf("%c", &ch);
if (ch == 'Y' || ch == 'y')
{
for (; i < n; i++)
stu[i] = stu[i + 1]; //被删除记录后面的记录均前移一位
n--; //记录总条数减1
printf("删除成功!");
}
return;
}
}
}
void search(struct student stu[])
{
char name[8];
int i;
printf("查找学生的记录。\n");
printf("请输入学生的姓名:");
scanf("%s", &name);
for (i = 0; i < n; i++)
{
if (strcmp(name, stu[i].name) == 0)
{
printf("找到该生的记录,如下所示:\n");
HH; //显示记录的标题
show(stu, i); //显示数组stu中的第i条记录
return;
}
}
printf("没有找到该生的记录。\n");
}
void sort(struct student stu[])
{
int i, j;
struct student t;
printf("按总成绩进行排序,");
for (i = 0; i < n - 1; i++) //双层循环实现总分的比较与排序
{
for (j = i + 1; j < n; j++)
{
if (stu[i].sum < stu[j].sum)
{
t = stu[i];
stu[i] = stu[j];
stu[j] = t;
}
}
}
printf("排序结果如下:\n");
showAll(stu); //显示排序后的所有记录
}
主函数实现
main.c
#include <stdio.h>
#include "student.h" //包含子函数原型文件student.h
int main()
{
struct student stu[50]; //用来保存学生记录,最多保存50条
int select, quit = 0;
while (1)
{
menu(); //调用子函数Menu输出菜单选项
scanf("%d", &select); //将用户输入的选择保存到select
switch (select)
{
case 1: //用户选择1,即添加记录,会转到这里来执行
add(stu); //调用子函数In,同时传递数组名stu
break;
case 2: //用户选择2,即显示记录,会转到这里来执行
showAll(stu); //调用子函数ShowAll,同时传递数组名stu
break;
case 3: //用户选择3,即修改记录,会转到这里来执行
modify(stu); //调用子函数Modify,同时传递数组名stu
break;
case 4: //用户选择4,即删除记录,会转到这里来执行
del(stu); //调用子函数Del,同时传递数组名stu
break;
case 5: //用户选择5,即查找记录,会转到这里来执行
search(stu); //调用子函数Search,同时传递数组名stu
break;
case 6: //用户选择6,即排序记录,会转到这里来执行
sort(stu); //调用子函数Sort,同时传递数组名stu
break;
case 0: //用户选择0,即退出系统,会转到这里来执行
quit = 1; //将quit的值修改为1,表示可以退出死循环了
break;
default:
printf("请输入0-6之间的数字\n");
break;
}
if (quit == 1)
break;
printf("按任意键返回主菜单!\n");
getchar(); //提取缓冲区中的回车键
getchar(); //起到暂停的作用
}
printf("程序结束!\n");
return 0;
}