学生管理系统,本质上是一个综合体,结合很多功能,也有很多技巧的应用.....
开头:学生信息录入
首先,是学生信息的录入环节,考虑到学生信息中包含姓名,年龄,各科成绩等,我这里用结构体实现开头部分
struct student
{
char StuID[LEN]; //学号
char Stuname[LEN];
int Stuage; //年龄
char Stusex; //性别
float score[3] //假定成绩三科,考虑小数,故浮点型
}; stu[N];
功能设计
考虑学生管理系统的大致需求:
- 帮助菜单
- 查找学生信息
- 删除学生信息
- 保存学生信息
- 刷新信息
- 退出信息
......(其余功能暂时省略)
因此,我用switch函数实现这部分
switch (num)
{
case 1: help();
break;
case 2: increase();
break;
case 3: search();
break;
case 4: del();
break;
case 5: save();
break;
case 6: fresh();
break;
case 7: tuichu();
break;
default:printf("输入有误,请重新输入!");
}
然后定义一个menu函数,将开关挨个对应。
//menu菜单实现
void menu()
{
printf("学生管理系统(模拟),请选择你需要的功能\n");
printf("1.使用帮助\n");
printf("2.增加信息\n");
printf("3.查询学生信息\n");
printf("4.删除学生信息\n");
printf("5.保存当前信息\n");
printf("6.刷新学生信息\n");
printf("7.退出系统\n");
}
现在,我们对每个功能进行函数实现
帮助部分设计
首先是使用帮助,这部分也是最简单的部分,文本即可。(我这里随便写了几句话,看看就好,别当真)
//help函数定义
void help()
{
printf("欢迎同学使用,这里有几个注意事项");
printf("在这里你可以增加,查询学生信息");
printf("祝你学习进步,开心");
}
增加信息部分设计
增加信息部分有点难度,这里我考虑到两个问题
1.增加的信息必须得对应上相应学生
2.如果输入查询并没有这个学生,那么信息也应该输入无效,而不应该留在系统里面。
这里我用 do while循环搜索的思路方法。(思路截图来自c primer plus书)
为啥用do while,是因为我希望每一遍的搜索想要的结果是否存在,然后插入进去。另外,可以定义一个标志,以至于可以在结束时候退出,大概格式为:
do
{
flag=1; //定义一个标志
while(flag)
{
flag=0;
...............
............
//我们的条件循环条件部分,满足flag1,不满足为0
flag=1
break;
//退出,完成
完善好我需要的条件,因此,完整代码如下:
//增加信息部分
void increase()
{
int i = n, j, flag, m = 0; //i代表时刻增加的人数
printf("请输入待增加的学生人数:\n");
scanf("%d", &m);
if (m > 0)
{
do
{
flag = 1;
while (flag)
{
flag = 0;
printf("请输入第%d位学生的学号:\n", i + 1);
scanf("%s", stu[i], StuID);
for (j = 0; j < i; j++)
{
if (strcmp(stu[i].stuID)) {
printf("该学号已经存在,请重新输入\n");
flag = 1;
break;
}
}
}
}
else {
printf("请输入第%d位学生姓名:\n", i + 1);
scanf("%s", stu[i].Stuname);
printf("请输入第%d位学生的年龄:\n", i + 1);
scanf("%d", &stu[i].Stuage);
getchar(); //防止上面的输入干扰下面的性别输入结果
printf("请输入第%d位学生性别:\n", i + 1);
scanf("%c", &stu[i].Stusex);
printf("请输入第%d位学生的语文成绩:\n", i + 1);
scanf("%f", &stu[i].score[0]);
printf("请输入第%d位学生的数学成绩:\n", i + 1);
scanf("%f", &stu[i].score[1]);
printf("请输入第%d位学生的英语成绩:\n", i + 1);
scanf("%f", &stu[i].score[2]);
i++;
}while (i < n + m);
}
n+= m;
printf("添加成功!\n");
system("pause");
}
这部分重点提醒下,一定要在性别前中加入一个getchar,不然影响后期输入结果。
查询部分设计
//查询部分设计
void search()
{
int i, num, flag;
char s1[LEN + 1];
printf("1.按学号查询\n");
printf("2.按姓名查询\n");
printf("3.退出本菜单\n");
while (1)
{
flag = 0;
printf("请输入您的选择:");
scanf("%d", &num);
switch (num)
{
case 1;
printf("请输入你想查询的学号;\n");
scanf("%s", s1);
for (i = 0; i < n; i++)
{
if (strcmp(stu[i].StuID, s1) == 0)
{
flag = 1;
printf("学号\t\t姓名\t\t性别\t\t年龄\t\t语文\t\t数学\t\t英语\n");
printf("%s\t\t%s\t\t%c\t\t%d\t\t%.2f\t\t%.2f\t\t%.2f\n", stu[i]);
}
}break;
case 2:
printf("请输入学生姓名:\n");
scanf("%s", s1);
for (i = 0; i < n; i++)
{
if (strcmp(stu[i].Stuname, s1) == 0)
{
flag = 1;
printf("学号\t\t姓名\t\t性别\t\t年龄\t\t语文\t\t数学\t\t英语\n");
printf("%s\t\t%s\t\t%c\t\t%d\t\t%.2f\t\t%.2f\t\t%.2f\n", stu[i].StuID, stu[i].Stuname, stu[i].Stusex, stu[i].Stuage, stu[i].score[0], stu[i].score[1], stu[i].score[2]);
}
}break;
case 3: return;
default: printf("请在1--3之间输入\n");
if (flag == 0)
printf("找不到该学生!\n请重新输入!");
}
}
删改部分功能设计
//删改部分功能设计
void del()
{
int i, j, flag;
char s1[LEN];
printf("请输入想删除的学生的学号:");
scanf("%s", s1);
flag = 0;
for (i = 0; i < n; i++)
{
if (strcmp(s1, stu[i].StuID) == 0)
{
flag = 1;
for (j = i; j < n - 1; j++)
{
stu[j] = stu[j + 1];
}
}
if (flag == 1)
break;
}
if(flag==0)
{
printf("该学号不存在!\n");
if (1 == flag)
{
printf("删除成功\n");
n--;
}
system("pause");
}
保存当前信息
即将输入的内容保存,这个还行,考察的指针部分的基本运用。
//保存函数
void save()
{
int i;
FILE* fp;
char filename[LEN + 1];
printf("请输入要保存的文件名称:\n");
scanf("%s", filename);
if ((fp = fopen(filename, "wt")) == NULL);
{
printf("打开文件失败\n");
exit(0);
}
for (i = 0; i < n; i++)
if (fwrite(&stu[i], sizeof(struct stuent), 1, fp)! = 1)
printf("保存失败!\n");
else
printf("保存成功!\n");
fclose(fp);
system("pause");
}
刷新信息
坦白的说,这部分是后面补进去的,有过参考,做这个部分的时候,我也想过,为什么我们这个系统要有刷新,刷新的目的是什么
和windows一样,假设某个信息没有显示出来,但是我们又不甘心或者确实是系统自身的问题,可以通过刷新的方式让它显示出来(我这里特意查了下百度百科里的解释)
//刷新信息
void fresh()
{
int i;
if (n == 0)
{
printf("您好,现在没有学生信息,请先增加学生信息或者刷新再来试试!\n");
}
else
{
printf("现在共有%d名学生:\n", n);
printf("学号\t\t姓名\t\t性别\t\t年龄\t\t语文\t\t数学\t\t英语\n");
for (i = 0; i < n; i++)
{
printf("%s\t\t%s\t\t%c\t\t%d\t\t%.2f\t\t%.2f\t\t%.2f\n", stu[i].StuID, stu[i].Stuname, stu[i].Stusex, stu[i].Stuage, stu[i].score[0], stu[i].score[1], stu[i].score[2]);
}
}
system("pause");
最后我还要啰嗦一句,把刷新做成功能,其实并不是很妥当,因为从用户角度思考,我查询没有,再返回主菜单,再刷新,又返回,实际步骤很麻烦。
个人最希望的状态是每个功能里可以刷新按钮就好,可惜目前能力,精力有限,因此如果聪明的你看到,希望可以在评论区指证,再次由衷感谢。
退出部分
void tuichu()
{
int h;//控制是否确认退出
printf("即将退出,确认请按1,取消请按0\n");
scanf("%d",&h);
if(h==1)
{
t=0;
printf("成功退出,感谢使用!\n");
}
else if(h==0)
{
printf("退出已取消!\n");
system("pause");
}
完整代码如下:
#include
#include
#include
#define N 50
#define LEN 15
int n = 0, t = 1; //t是循环标志,不代表数值
void menu(); //总功能
void help(); //帮助部分
void increase(); //增加信息
void search();//查询信息
void del(); //删除信息
void save(); //保存信息
void fresh(); //刷新信息
void tuichu(); //退出信息
//定义结构体,信息录入
struct student
{
char StuID[LEN]; //学号
char Stuname[LEN];
int Stuage; //年龄
char Stusex; //性别
float score[3]; //假定成绩三科
}stu[N];
//主函数部分
int main()
{
int num;
while (t)
{
menu();
printf("您好,请输入菜单编号:");
scanf("%d", &num);
switch (num)
{
case 1: help();
break;
case 2: increase();
break;
case 3: search();
break;
case 4: del();
break;
case 5: save();
break;
case 6: fresh();
break;
case 7: tuichu();
break;
default:printf("输入有误,请重新输入!");
}
}
system("pause");
return 0;
}
//menu菜单实现
void menu()
{
printf("学生管理系统(模拟),请选择你需要的功能\n");
printf("1.使用帮助\n");
printf("2.增加信息\n");
printf("3.查询学生信息\n");
printf("4.删除学生信息\n");
printf("5.保存当前信息\n");
printf("6.刷新学生信息\n");
printf("7.退出系统\n");
}
//帮助菜单
void help()
{
printf("欢迎同学使用");
printf("在这里你可以增加,查询学生信息");
printf("祝你学习进步,开心");
system("pause");
}
//增加信息部分
void increase()
{
int i = n, j, flag, m = 0;//i代表增加学生信息过程中任意时刻的学生人数
printf("\n请输入待增加的学生人数:\n");
scanf("%d", &m);
if (m > 0) {
do {
flag = 1;
while (flag)
{
flag = 0;
printf("请输入第%d位学生的学号:\n", i + 1);//第几位学生从1开始计数,而stu[]从零开始,需要加1
scanf("%s", stu[i].StuID);
//判断学号是否重复
for (j = 0; j < i; j++) {
if (strcmp(stu[i].StuID, stu[j].StuID) == 0) {
printf("该学号已经存在,请重新输入!\n");
flag = 1;
break;
}
}
}
printf("请输入第%d位学生姓名:\n", i + 1);
scanf("%s", stu[i].Stuname);
printf("请输入第%d位学生年龄:\n", i + 1);
scanf("%d", &stu[i].Stuage);
getchar();//处理上面输入的换行符,不然系统会把换行符当做一个字符赋值给性别
printf("请输入第%d位学生性别:\n", i + 1);
scanf("%c", &stu[i].Stusex);
printf("请输入第%d位学生的语文成绩:\n", i + 1);
scanf("%f", &stu[i].score[0]);
printf("请输入第%d位学生的数学成绩:\n", i + 1);
scanf("%f", &stu[i].score[1]);
printf("请输入第%d位学生的英语成绩:\n", i + 1);
scanf("%f", &stu[i].score[2]);
i++;
} while (i < n + m);//只要当前学生人数还没到达添加后的总人数,就得继续添加
}
n += m;// 添加完成,系统人数n的值也要增加
printf("添加完成!!!\n");
system("pause");
}
//查询部分设计
void search()
{
int i, num, flag;
char s1[LEN + 1];
printf("1.按学号查询\n");
printf("2.按姓名查询\n");
printf("3.退出本菜单\n");
while (1)
{
flag = 0;
printf("请输入您的选择:");
scanf("%d", &num);
switch (num)
{
case 1:
printf("请输入你想查询的学号;\n");
scanf("%s", s1);
for (i = 0; i < n; i++)
{
if (strcmp(stu[i].StuID, s1) == 0)
{
flag = 1;
printf("学号\t\t姓名\t\t性别\t\t年龄\t\t语文\t\t数学\t\t英语\n");
printf("%s\t\t%s\t\t%c\t\t%d\t\t%.2f\t\t%.2f\t\t%.2f\n", stu[i]);
}
}break;
case 2:
printf("请输入学生姓名:\n");
scanf("%s", s1);
for (i = 0; i < n; i++)
{
if (strcmp(stu[i].Stuname, s1) == 0)
{
flag = 1;
printf("学号\t\t姓名\t\t性别\t\t年龄\t\t语文\t\t数学\t\t英语\n");
printf("%s\t\t%s\t\t%c\t\t%d\t\t%.2f\t\t%.2f\t\t%.2f\n", stu[i].StuID, stu[i].Stuname, stu[i].Stusex, stu[i].Stuage, stu[i].score[0], stu[i].score[1], stu[i].score[2]);
}
}break;
case 3: return;
default: printf("请在1--3之间输入\n");
if (flag == 0)
printf("找不到该学生!\n请重新输入!");
}
}
}
//删改部分功能设计
void del()
{
int i, j, flag;
char s1[LEN];
printf("请输入需要删除的学生学号:\n");
scanf("%s", s1);
flag = 0;
for (i = 0; i < n; i++)
{
if (strcmp(s1, stu[i].StuID) == 0)
{
flag = 1;
for (j = i; j < n - 1; j++)
{
stu[j] = stu[j + 1];//直接把后面的学生都往前移动一位
}
}
if (flag == 1) break;//说明已经找到了需要删除的学生,结束循环
}
if (0 == flag)
{
printf("该学号不存在!!!\n");
}
else if (1 == flag)
{
printf("删除成功\n");
n--;
}
system("pause");
}
//保存函数
void save()//把学生信息保存到文件
{
int i;
FILE* fp;
char filename[LEN + 1];
printf("请输入要保存的文件名:\n");
scanf("%s", filename);
if ((fp = fopen(filename, "w")) == NULL)
{
printf("打开文件失败!\n");
exit(0);
}
for (i = 0; i < n; i++)
if (fwrite(&stu[i], sizeof(struct student), 1, fp) != 1)
printf("保存失败!!\n");
printf("保存成功!!!\n");
fclose(fp);
system("pause");
}
//刷新信息
void fresh()
{
int i;
if (n == 0)
{
printf("您好,现在没有学生信息,请先增加学生信息或者刷新再来试试!\n");
}
else
{
printf("现在共有%d名学生:\n", n);
printf("学号\t\t姓名\t\t性别\t\t年龄\t\t语文\t\t数学\t\t英语\n");
for (i = 0; i < n; i++)
{
printf("%s\t\t%s\t\t%c\t\t%d\t\t%.2f\t\t%.2f\t\t%.2f\n", stu[i].StuID, stu[i].Stuname, stu[i].Stusex, stu[i].Stuage, stu[i].score[0], stu[i].score[1], stu[i].score[2]);
}
}
system("pause");
}
//删除信息部分
void tuichu()
{
int h;//控制是否确认退出
printf("即将退出,确认请按1,取消请按0\n");
scanf("%d", &h);
if (h == 1)
{
t = 0;
printf("成功退出,感谢使用!\n");
}
else if (h == 0)
{
printf("退出已取消!\n");
system("pause");
}
}
运行结果为: