实现要求如下所示:
学生信息包括:学号,姓名,年龄,性别,出生年月,地址,电话等。试设计一学生信息管理系统,使之能提供以下功能:系统以菜单方式工作(用键盘输入1~6之间的数来选择功能)
(1)学生信息录入功能(学生信息用文件保存)
(2)学生信息浏览功能
(3)查询功能:按学号查询和按姓名查询
(4)学生信息的删除:(按学号进行删除)
(5)学生信息的修改:(按学号进行修改某学生的姓名)
(6)退出。
学生信息录入功能实现
创建一个函数来实现学生信息的录入功能 void Input(),首次要求我们从键盘输入一个数来确定我们要录入几个人的信息,然后通过循环来一一对他们的各个信息进行录入,最后在通过一个内嵌循环来对学生的学生一个个进行比对,如果有重复学号即代表输入有误,会提示输出错误,请重复输入!如果录入信息没有错,那么将会提示录入完毕!按回车键实现清屏返回主菜单界面。
参考代码如下:
void Input() //输入学生信息函数
{
int i = 0, n = 0, flag = 0;
printf("请输入要添加的学生人数:");
scanf("%d", &n);
s.sum = n;
while (i < n) {
printf("请输入第%d个学生的学号:\n", i + 1);
scanf("%s", stu[i].num);
printf("请输入第%d个学生的姓名:\n", i + 1);
scanf("%s", stu[i].name);
printf("请输入第%d个学生的年龄:\n", i + 1);
scanf("%d", &stu[i].age);
printf("请输入第%d个学生的性别:\n", i + 1);
scanf("%s", stu[i].sex);
printf("请输入第%d个学生的出生年月:\n", i + 1);
scanf("%s", stu[i].time);
printf("请输入第%d个学生的地址:\n", i + 1);
scanf("%s", stu[i].add);
printf("请输入第%d个学生的电话:\n", i + 1);
scanf("%s", stu[i].mail);
for (int j = 0; j < i; j++) { //通过比较学号排查输入是否有误,如果有则重新输入
if (strcmp(stu[i].num, stu[j].num) == 0) {
i--;
printf("输入错误,请重新输入!\n");
printf("——————————\n");
printf("\n");
}
}
i++;
}
printf("录入完毕!\n");
system("pause");
system("cls");
}
学生信息浏览功能实现
创建一个函数void Browse()用来浏览刚才录入的学生信息,如果学生人数为0,则提示当前系统无学生信息,反之则用循环遍历录入在系统里的学生信息。这一功能相对比较容易实现。
参考代码如下:
void Browse() //浏览学生信息函数
{
int i = 0;
printf("所有的学生信息为:\n");
printf("学生学号 学生姓名 年龄 性别 出生年月 地址 电话 \n");
printf("————————————————————————\n");
if (s.sum == 0)
printf("当前系统无学生信息!\n");
for (i = 0; i < s.sum; i++) {
printf("%6s %7s %6d %4s %5s %6s %6s\n", stu[i].num, stu[i].name, stu[i].age, stu[i].sex, stu[i].time, stu[i].add, stu[i].mail);
}
printf("\n");
}
学生信息查询功能实现
创建一个函数void Seek()用以查询刚才录入的学生信息,在这块功能里,我设置一个小菜单并设立两个查询方向:1.按学号查询。2.按姓名查询。从键盘录入要查询的信息,然后通过循环一一对系统里有的学生信息进行比对,如果查找到了则返回你要查找的学生信息,如果找不到则提示查询不到你要找的学生!,最后在设置一个退出小菜单并返回主菜单界面的功能,这一块的功能就基本实现了。
参考代码如下:
void Seek() //查询学生信息函数
{
int select = 0, flag = 0;
char s1[10];
while (1) {
printf("——————————\n");
printf("—— 1、学号查询——\n");
printf("—— 2、姓名查询——\n");
printf("—— 3、退出 ——\n");
printf("请选择对应编号:\n");
scanf("%d", &select);
switch (select) {
case 1:
printf("请输入你要查询的学号:\n");
scanf("%s", s1);
for (int i = 0; i < s.sum; i++) {
if (strcmp(s1, stu[i].num) == 0) {
flag = 1;
printf("你要查找的学生信息如下:\n");
printf("学生学号 学生姓名 年龄 性别 出生年月 地址 电话 \n");
printf("————————————————————————\n");
printf("%6s %7s %6d %4s %5s %6s %6s\n", stu[i].num, stu[i].name, stu[i].age, stu[i].sex, stu[i].time, stu[i].add, stu[i].mail);
}
}
if (flag == 0)
printf("查询不到你要找的学生!\n");
printf("\n");
break;
case 2:
printf("请输入你要查询的姓名:\n");
scanf("%s", s1);
for (int i = 0; i < s.sum; i++) {
if (strcmp(s1, stu[i].name) == 0) {
flag = 1;
printf("你要查找的学生信息如下:\n");
printf("学生学号 学生姓名 年龄 性别 出生年月 地址 电话 \n");
printf("————————————————————————\n");
printf("%6s %7s %6d %4s %5s %6s %6s\n", stu[i].num, stu[i].name, stu[i].age, stu[i].sex, stu[i].time, stu[i].add, stu[i].mail);
}
}
if (flag == 0)
printf("查询不到你要找的学生!\n");
printf("\n");
break;
case 3:
system("cls");
return ;
default:
printf("请在1-3之间选择!\n");
printf("\n");
}
}
}
学生信息删除功能实现
创建一个函数void Delete()来实现删除学生信息的功能,这一部分比较容易实现,先从键盘上输入要删除学生的学号,然后再通过循环对系统里的学生信息一一进行比对,如果找到这名学生,那么就将后面一位学生的信息覆盖到当前学生的信息,再用内嵌循环将后面的每一位学生的信息赋给前面一位即可,同时显示删除成功并将学生总数sum–。如果查询不到要删除的学生,则提示查询不到你要删除的学生。
参考代码如下:
void Delete() //删除学生信息函数
{
int flag = 0;
char s1[10];
printf("请输入要删除的学号:\n");
scanf("%s", s1);
for (int i = 0; i < s.sum; i++) {
if (strcmp(s1, stu[i].num) == 0) {
flag = 1;
for (int j = i; j < s.sum - 1; j++) {
stu[j] = stu[j + 1];
}
}
}
if (flag == 0)
printf("查询不到你要删除的学生信息!\n");
if (flag == 1) {
printf("删除成功!\n");
s.sum--;
}
}
学生信息修改功能实现
创建一个函数void Modify()来实现对学生信息的修改操作,首先从键盘输入要修改学生的学号,用循环比对学生信息,如果找到了要修改的学生信息,则进入小菜单,菜单提示按编号选择你要修改的学号、姓名、年龄、性别、出生年月、地址、电话等相对应的信息,再构造一个switch分支结构实现你要修改的学生信息的功能,完毕提示你修改成功!最后再构造一个退出功能退出小菜单返回主菜单界面。
参考代码如下:
void Modify() //修改学生信息函数
{
int select = 0;
char s1[10], s2[10], s3[Max];
int flag = 0;
printf("请输入要修改的学生学号:\n");
scanf("%s", s1);
for (int i = 0; i < s.sum; i++) {
if (strcmp(s1, stu[i].num) == 0) {
flag = i;
printf("——————————\n");
printf("—— 1、修改学号——\n");
printf("—— 2、修改姓名——\n");
printf("—— 3、修改年龄——\n");
printf("—— 4、修改性别——\n");
printf("—— 5、修改出生年月\n");
printf("—— 6、修改地址——\n");
printf("—— 7、修改电话——\n");
printf("—— 8、退出 ——\n");
while (1) {
printf("请选择对应编号:\n");
scanf("%d", &select);
switch (select) {
case 1:
printf("请输入新的学号:\n");
scanf("%s", s2);
strcpy(stu[flag].num, s2);
printf("修改成功!\n");
break;
case 2:
printf("请输入新的姓名:\n");
scanf("%s", s3);
strcpy(stu[flag].name, s3);
printf("修改成功!\n");
break;
case 3:
printf("请输入新的年龄:\n");
scanf("%d", &stu[i].age);
printf("修改成功!\n");
break;
case 4:
printf("请输入新的性别:\n");
scanf("%s", s2);
strcpy(stu[flag].sex, s2);
printf("修改成功!\n");
break;
case 5:
printf("请输入新的出生年月:\n");
scanf("%s", s3);
strcpy(stu[flag].time, s3);
printf("修改成功!\n");
break;
case 6:
printf("请输入新的地址:\n");
scanf("%s", s3);
strcpy(stu[flag].add, s3);
printf("修改成功!\n");
break;
case 7:
printf("请输入新的电话:\n");
scanf("%s", s3);
strcpy(stu[flag].mail, s3);
printf("修改成功!\n");
break;
case 8:
system("cls");
return;
}
}
}
}
}
学生信息保存功能实现
创建一个函数vpid Save()来实现学生信息用文件来保存。首先声明一个指向FILE的类型的对象的指针,*fp是指向文件结构体的指针变量,通过fp可找到存放某个文件信息的结构变量,根据这个结构变量的信息找到该文件,实施对文件的操作。最后别忘了fclose(fp)关闭文件。
参考代码如下:
void Save()
{
int i;
FILE* fp;
fp = fopen("C:\\Users\\DELL\\Desktop\\student.txt", "w");
for (i = 0; i < s.sum; i++)
{
fprintf(fp, "%s %s %d %s %s %s %s %s\n", stu[i].num, stu[i].name, stu[i].age, stu[i].sex, stu[i].time, stu[i].add, stu[i].mail);
}
fclose(fp);
system("cls");
}
主菜单界面功能实现
创建一个函数void Mene()来实现对学生信息管理系统主菜单的设计,然后键盘输入一个数来选择编号所对应的功能,用swith分支结构来实现对各个功能函数的调用以及退出系统的操作。
参考代码如下:
void Menu() //菜单函数
{
int num = 0;
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(" ——————————————————————————\n");
printf("请选择对应编号:\n");
scanf("%d", &num);
switch (num) {
case 1:Input();
break;
case 2:Browse();
break;
case 3:Seek();
break;
case 4:Delete();
break;
case 5:Modify();
break;
case 6:Save();
break;
case 7:Exit();
break;
default:printf("请在序号1-7之间选择!\n");
}
}
到这里基本的函数功能内容和相关代码实现都已经介绍完毕,接下来谈谈实现代码的优缺点。
优点
1、程序可执行多个选项,每次输入选项前清除缓存,并重新显示菜单。
2、对输入菜单选项以及输入数据进行合法性检验。
3、表格的打印较为整齐。
4、采用了文件保存学生的信息,每次运行系统后学生的信息不会随着系统的关闭而被系统自动的释放,而是通过文件的形式被保存了下来。
不足之处
1、使用了静态数组存储学生信息,如果采用动态数组存储数组,那么所占用的内存将会更加的少。
2、对部分数据的合法性还缺少了判断,并不能完全避免非法数据的输入。
3、通篇代码基本都是使用了暴力循环遍历的方法查找,可以适当使用例如二分查找,模糊查询算法,提高容错率的同时又减少了时间复杂度,提高代码的运行效率。
收获与学习体会
一口气在写完完整代码后差不多三百行左右的样子,调试的时候冒出来各种而样的小毛病小bug,前面改完后面也要改,牵一发而动全身,所以我注意到还是分部进行调试更轻松,写完一个部分的代码,就debug一下,有问题就及时修改,这样在后期的编写过程中就不会再要修改了,同时还要对自己的代码进行一些适当的润色,让自己的代码更加健壮,正如很多前辈所说,敲完代码并不意味着程序的完成,后续的调试往往代表着更严峻的考验。
我们往往在写一些简单代码的时候,我们没有太过的在意内存空间的占用,变量和函数的命名这些小小的细节,比如我在完成这篇学生管理系统设计时用到的就是静态数组,占用了很多不需要的空间,在以后的学习乃至工作中,我们可以尝试动态分配数组来减少对内存的占用,在变量和函数的命名方面,可以尽量用驼峰命名法来让自己的变量和函数看起来更加规范和整洁,虽然会使得变量和函数的名字变得更长,但是冗长的同时会时时刻刻的提醒我这个变量以及函数的作用,这样对以后长时间的编程来讲是有很大好处的。
最后的最后,要说到注释的问题,再平常的学习过程中,可能面对的都是一些比较简洁代码,其容易理解的程度导致我们基本无法养成写注释的习惯,觉得又鸡肋又浪费时间,但其实写注释也就是在解释我们每一步在做着什么样的工作,有利于理清我们的思路,更好地投入到接下来的编写过程中,同时也能帮助其他人看懂我们的代码,对己对他人,都是大有裨益的事情。