用C语言设计简单的学生成绩信息管理系统

  • 介绍
  • 代码
    • 结构体数组的定义
    • home_page() 函数
    • add_infor() 函数
    • browse_infor() 函数
    • find_infor() 函数
    • modify_infor() 函数
    • sort_score() 函数
    • delete_infor() 函数
    • writetofile() 函数
    • readfromfile() 函数
    • main() 函数
    • 完整代码
  • 结束语

介绍

  • 软件方面采用的是 Visual Studio 2019 IDE 工具。
  • 程序方面采用结构体数组,成员包括学号、姓名以及一科成绩。程序整体采用分模块编程形式,包括主函数在内共10个函数,实现功能有信息的录入、浏览、查询、修改、删除、数据保存到文件以及成绩的排序。程序比较简单,结构体成员只有三个,没有什么技术含量,后期看看有没有能力用链表来编写这个程序。

代码

  • 结构体数组的定义

函数开始前,是结构体数组的定义。这里直接使用typedef定义结构体数组,一步到位。后续可用STUDENT来进行变量声明了


  • home_page() 函数

这个是主界面的显示函数,完整的声明为:void home_page(),无形参,无返回值,单纯用printf()函数打印的界面。
完整代码

void home_page()
{printf("\n\t\t******************************** \n");printf("\t\t     学生成绩信息管理系统       \n\n");printf("\t\t        1、录入信息            \n\n");printf("\t\t        2、浏览信息            \n\n");printf("\t\t        3、查询信息            \n\n");printf("\t\t        4、修改信息            \n\n");printf("\t\t        5、成绩排序            \n\n");printf("\t\t        6、删除信息            \n\n");printf("\t\t        7、向文件写入数据       \n\n");printf("\t\t        8、从文件读出数据       \n\n");printf("\t\t        9、退出系统            \n\n");printf("\t\t******************************** \n\n");
}

运行效果

其中,“输入标号选择功能:”字样是在 main() 函数中调用 home_page() 函数后,打印的提示语。


  • add_infor() 函数

这是实现信息录入功能的函数,完整的函数声明是:int add_infor(STUDENT stu[], int n),形参为结构体数组stu[]和结构体数组个数n,返回值n+i是添加完信息后的结构体数组的总个数。函数内部,i变量是每次添加的信息的个数,sign变量作为连续输入的标志。这里判断是否连续输入,我原来用的方法是判断stu[n+i].num的值是否为-1,编译成功没有报错,但是实际运行过程中会出现一些问题,应该是逻辑上的问题。我暂且换成每输入一条信息后,判断是否继续输入第二条信息,实际使用时会有一些繁琐,但总体效果相差无几。
完整代码

int add_infor(STUDENT stu[], int n)
{int i = 0;char sign = 'Y';while ((sign == 'Y') || (sign == 'y')){printf("\n\t\t\t学号:");scanf("\t\t%s", stu[n + i].num);printf("\t\t\t姓名:");scanf("\t\t%s", stu[n + i].name);printf("\t\t\t成绩:");scanf("\t\t%f", &stu[n + i].score);printf("\n\t\t\t是否继续录入?(Y/N):");sign = getchar();i++;}return (n + i);
}

上述代码在 Visual Studio 2019 IDE 中编译时,scanf()函数会报出警告,警告代码为:C6031,说明为:返回值被忽略。解决方法有两个,第一种是将scanf替换为scanf_s,我没有采用这种方法,因为scanf_s并不是 C 语言中的,而是 Visual Studio 开发工具提供的一个功能相同的安全标准输入函数,如果换为scanf_s,在另一个编译器下就可能会出问题;第二种是使用#define _CRT_SECURE_NO_WARNINGS 1,具体做法可百度查找,经实测,这种方法是可行的。但是,如果两种方法都不采取,即不消除这个警告,实际上对程序的正确运行也没有影响。
运行效果

“录入学生成绩信息”字样由 main() 函数在调用 add_infor() 函数前打印


  • browse_infor() 函数

这是实现浏览录入信息功能的函数,完整声明为:void browse_infor(STUDENT stu[], int n),形参为结构体数组stu[]和结构体数组个数n,无返回值。函数内部,i是作为循环控制变量,传入数组个数n,然后通过 for 循环,依次打印出结构体成员的值。
完整代码

void browse_infor(STUDENT stu[], int n)
{int i;printf("\n\n");printf("\t\t学号\t姓名\t成绩\n\n");for (i = 0; i < n; i++){printf("\t\t%s\t%s\t %3.1f\n",stu[i].num,stu[i].name,stu[i].score);}
}

运行效果

“浏览学生成绩信息”字样由 main() 函数在调用 browse_infor() 函数前打印


  • find_infor() 函数

这是实现信息查找功能的函数,完整的声明为:void find_infor(STUDENT stu[], int n),形参为结构体数组stu[]和结构体数组个数n,无返回值。函数内部,又分为通过学号查找和通过姓名查找两种方式,变量option存放键入的选项,两个字符串数组分别存放查找的学号和姓名。先选择查找方式,输入对应方式的值,然后遍历数组,通过strcmp()函数判断数组中是否有与输入相同的值,若无相同的值则显示“未找到!”的信息,若有相同值则将该结构体成员的信息打印到屏幕上。
完整代码

void find_infor(STUDENT stu[], int n)
{int option;int i = 0;char search_num[10] = { 0 };char search_name[20] = { 0 };printf("\n\t\t\t1、按学号查找\n");printf("\t\t\t2、按姓名查找\n");printf("\n\t\t\t请选择相应的选项:");scanf("%d",&option);system("cls");if (1 == option){printf("\n\t\t请输入要查找的学号:");scanf("%s", search_num);while ((strcmp(stu[i].num, search_num) != 0) && i < n){i++;}}if (2 == option){printf("\n\t\t请输入要查找的姓名:");scanf("%s", search_name);while ((strcmp(stu[i].name, search_name) != 0) && i < n){i++;}}if (i == n){printf("\n\t\t未找到!");return;}printf("\n\t\t学号:%s\n", stu[i].num);printf("\t\t姓名:%s\n", stu[i].name);printf("\t\t成绩:%3.1f\n", stu[i].score);
}

从上述代码中可以看到,在定义两个字符串数组时,均赋了初值0,若此处没有赋初值0时,上段代码在 Visual Studio 2019 IDE 中编译时,strcmp()函数会报警告,警告代码为:C6054,说明为:可能没有为字符串“xxx”添加字符串零终止符。深入了解strcmp()函数可以知道,其功能是两个字符串自左向右逐个字符相比(按 ASCII 值大小相比较),直到出现不同的字符或遇 ‘\0’ 为止。所以此处在定义字符串数组时,将其初始化为 ‘\0’ ,即char search_num[10] = { 0 };,就可以消除此类警告。
运行效果


  • modify_infor() 函数

这是实现信息修改功能的函数,函数声明为:int modify_infor(STUDENT stu[], int n),形参为结构体数组stu[]和结构体数组个数n。函数内部,可选择通过学号查找修改和通过姓名查找修改两种方式。查找部分与void find_infor(STUDENT stu[], int n)函数一致;修改部分有修改学号、姓名、成绩三个选项,修改的实现形式是:通过查找部分得出待修改的数组下标,然后通过strcpy()函数,将输入的修改后的学号和姓名赋值给下标对应的成员,分数的修改则直接赋值。
完整代码

int modify_infor(STUDENT stu[], int n)
{int option, choice;int i = 0;char old_temp[20] = { 0 };char new_temp[20] = { 0 };float new_score;printf("\n\t\t\t1、按学号查找修改\n");printf("\t\t\t2、按姓名查找修改\n");printf("\n\t\t请输入选项选择功能:");scanf("%d", &option);system("cls");if (1 == option){printf("\n\t\t请输入学号:");scanf("%s", &old_temp);while ((strcmp(stu[i].num, old_temp) != 0) && i < n){i++;}if (i == n){printf("\n\t\t未找到!");}}if (2 == option){printf("\n\t\t请输入姓名:");scanf("%s", &old_temp);while ((strcmp(stu[i].name, old_temp) != 0) && i < n){i++;}if (i == n){printf("\n\t\t未找到!");}}printf("\n\t\t待修改学生的信息:\n");printf("\n\t\t学号:%s\n\t\t姓名:%s\n\t\t成绩:%3.1f\n", stu[i].num, stu[i].name, stu[i].score);printf("\n\t\t请选择要修改的信息(1.学号 2.姓名 3.成绩):");scanf("%d", &choice);if (1 == choice){printf("\n\t\t输入修改后的学号:");scanf("%s", &new_temp);strcpy(stu[i].num, new_temp);printf("\t\t修改成功!\n");}if (2 == choice){printf("\n\t\t输入修改后的姓名:");scanf("%s", &new_temp);strcpy(stu[i].name, new_temp);printf("\t\t修改成功!\n");}if (3 == choice){printf("\n\t\t输入修改后的成绩:");scanf("%f", &new_score);stu[i].score = new_score;printf("\t\t修改成功!\n");}
}

此函数中的两个字符串数组在定义时,也需要赋初值,以消除函数strcmp()strcpy()使用时的警告。
运行效果


  • sort_score() 函数

此函数完整声明为:void sort_score(STUDENT stu[], int n),形参为结构体数组stu[]和结构体数组个数n,实现的功能是排序,用的是冒泡排序法,按从小到大的顺序给成绩排序。具体实现形式就是,通过两层循环,外层循环是排序趟数,内层循环是每趟比较的次数,相邻两元素比较,若前者大于后者,则两者进行交换,此时为顺序,即从小到大;若前者小于后者且两者交换,则为逆序,即从大到小。此函数为顺序,且在交换两者值时,学号和姓名使用strcpy()函数,成绩的交换使用指针。
完整代码

void sort_score(STUDENT stu[], int n)
{int i, j;float * p, * q, s;char temp[20];for (i = 0; i < n - 1; i++){for (j = 0; j < n - 1 - i; j++){if (stu[j].score > stu[j + 1].score){strcpy(temp, stu[j].num);strcpy(stu[j].num, stu[j + 1].num);strcpy(stu[j + 1].num, temp);strcpy(temp, stu[j].name);strcpy(stu[j].name, stu[j+1].name);strcpy(stu[j+1].name,temp);p = &stu[j].score;q = &stu[j + 1].score;s = *p;*p = *q;*q = s;}}}
}

运行效果


  • delete_infor() 函数

此函数是信息删除函数,完整声明为:int delete_infor(STUDENT stu[], int n),形参为结构体数组stu[]和结构体数组个数n,返回值是删除后的数组个数。函数内部,可通过按学号和按姓名两种方式查找并删除,其中查找部分与void find_infor(STUDENT stu[], int n)函数一致;删除部分的实现形式是,从查找部分获得找到的数组下标,从下标处开始,将后一值赋给前一值,直至数组的末尾,以此实现删除的功能。
完整代码

int delete_infor(STUDENT stu[], int n)
{char search_num[10] = { 0 };char search_name[20] = { 0 };int i = 0;int j;int option;printf("\n\t\t\t1、按学号查找删除\n");printf("\t\t\t2、按姓名查找删除\n");printf("\n\t\t\t请输入选项选择功能:");scanf("%d", &option);system("cls");if (1 == option){printf("\n\t\t请输入要删除的学生的学号:");scanf("%s", &search_num);while ((strcmp(stu[i].num, search_num)) != 0 && (i < n)){i++;}if (i == n){printf("\t\t未找到!\n");return n;}}if (2 == option){printf("\n\t\t请输入要删除的学生的姓名:");scanf("%s", &search_name);while ((strcmp(stu[i].num, search_name) != 0) && (i < n)){i++;}if (i == n){printf("\t\t未找到!\n");return n;}}for (j = i; j < n; j++){strcpy(stu[j].num, stu[j + 1].num);strcpy(stu[j].name, stu[j + 1].name);stu[j].score = stu[j + 1].score;}printf("\t\t删除成功!\n");return (n - 1);
}

注意此函数的返回值,由于删除了一条信息,即从结构体数组中删除了一项,所以返回值应当是传入参数n减去1之后的值,即返回值return (n-1);
运行效果


  • writetofile() 函数

此函数的功能是将录入的数据保存到文件中,完整声明为:void writetofile(STUDENT stu[], int n),形参为结构体数组stu[]和结构体数组个数n。函数内部,用 FILE 结构体类型定义文件类型的指针变量 fp,输入要写入的文件的名称,然后以只写 “w” 的方式,向文件写入数据,若指定的文件不存在则创建它,如果存在则先删除它再重建一个新文件,首先向文件内写结构体数组的个数,然后通过 while 循环,将所有信息写入文件中,最后fclose(fp)关闭文件。
完整代码

void writetofile(STUDENT stu[], int n)
{FILE* fp;int i = 0;char filename[20] = { 0 };printf("\n\t\t\t请输入文件名称:");scanf("%s", filename);if ((fp = fopen(filename, "w")) == NULL){printf("\n\t\t\t打开文件失败!\n");return;}fprintf(fp, "%d\n", n);while (i < n){fprintf(fp, "%-6s%-10s%3.1f\n", stu[i].num, stu[i].name, stu[i].score);i++;}fclose(fp);printf("\n\t\t\t写入文件成功!\n");
}

由于只需要向文件写数据,所以fopen()中 mode 参数只需要"w"即可,数据写入文件成功后,一定要使用fclose(fp)关闭文件。
运行效果


“向文件写入数据”字样由 main() 函数在调用 writetofile() 函数前打印


  • readfromfile() 函数

此函数的功能是从文件中读出数据,完整声明为:int readfromfile(STUDENT stu[], int n),形参为结构体数组stu[]和结构体数组个数n,返回值为读入数据后的数组总个数。函数内部,用 FILE 结构体类型定义文件类型的指针变量 fp,输入要读出数据的文件的名称,以只读方式,通过 while 循环,从文件中读出数据,存放到数组中,然后将读到的数据个数加上传进的参数 n 作为返回值,最后关闭文件。
完整代码

int readfromfile(STUDENT stu[], int n)
{FILE* fp;int i, num;char filename[20];i = 0;printf("\n\t\t\t请输入文件名称:");scanf("%s", filename);if ((fp = fopen(filename, "r")) == NULL){printf("\n\t\t\t无法打开文件!\n");return n;}fscanf(fp, "%d", &num);while (i < num){fscanf(fp, "%-5s%-10s%3.1f\n", stu[n + i].num, stu[n + i].name, stu[n + i].score);i++;}n += num;fclose(fp);printf("\n\t\t\t读出数据成功!\n");return n;
}

同样,在打开文件并执行操作完毕后,需要fclose(fp)来关闭文件。注意,此函数的返回值应该是读到的数据个数 num 加上传进的参数 n ,返回的才是此时总的数组个数。
运行效果

“从文件读出数据”字样由 main() 函数在调用 readfromfile() 函数前打印


  • main() 函数

main函数部分,主要是由while(1)死循环构成的,循环内部首先调用home_page()函数显示主界面,然后通过 switch-case 语句,来匹配用户输入的选项。

完整代码

int main()
{int select = 0;int n = 0;while (1){system("cls");home_page();printf("\t\t输入标号选择功能: ");scanf("%d", &select);switch (select){case 1:system("cls");printf("\n\t\t********录入学生成绩信息********\n");n = add_infor(stu, n);break;case 2:system("cls");printf("\n\t\t********浏览学生成绩信息********\n");browse_infor(stu, n);getchar();break;           case 3:system("cls");printf("\n\t\t**********查询学生信息**********\n");find_infor(stu, n);getchar();break;case 4:system("cls");printf("\n\t\t*********修改学生信息*********\n");n = modify_infor(stu, n);getchar();break;case 5:system("cls");printf("\n\t\t*********按成绩排序*********\n");sort_score(stu, n);printf("\n\t\t\t排序成功!");getchar();break;  case 6:system("cls");printf("\n\t\t*********删除学生信息*********\n");n = delete_infor(stu, n);getchar();break;case 7:system("cls");printf("\n\t\t********向文件写入数据********\n");writetofile(stu, n);getchar();break;case 8:system("cls");printf("\n\t\t********从文件读出数据********\n");n = readfromfile(stu, n);getchar();break;default:system("cls");printf("\n\n\t\t**********谢谢使用!**********\n");exit(0);break;}getchar();}
}

注意,switch-case 语句的每个 case 结束都应加上break;,且最后要加上default,同时,为了美观,在每个 case 语句调用函数前,都加上system("cls")清屏函数;在调用后,加上getchar ()语句等待用户操作。


  • 完整代码

链接: 完整代码

结束语

第一次写博客,方方面面的都有些不熟悉,脑子里有很多想法,但无从下手,拿了以前写的程序作主要内容,进行一次尝试。虽然内容啥的都很简单,程序也没有什么技术含量,但这是一次从0到1的尝试吧,以后也会继续努力。文中如有错误之处,还请指正,如遇大佬,还请多多指教!

C语言编写学生成绩信息管理系统相关推荐

  1. c语言编写简单的成绩管理系统,用c语言编写学生成绩管理系统

    <用c语言编写学生成绩管理系统>由会员分享,可在线阅读,更多相关<用c语言编写学生成绩管理系统(9页珍藏版)>请在人人文库网上搜索. 1.include#include#inc ...

  2. C语言编写学生成绩管理系统

    文章链接:https://codemouse.online/archives/2020-06-04-16-07-48 需求 用C语言编写学生成绩管理系统,要求该系统可 对学生操作:添加和删除操作. 可 ...

  3. 任务2 学生成绩信息管理系统

    系列文章 任务2 学生成绩信息管理系统 某班级学生C语言第一次正考的成绩存于数据文件score.txt中,记录了学生学号.姓名和考试成绩,bk.txt文件中记录了补考学生的学号.姓名和补考成绩,编写程 ...

  4. 学籍信息管理系统c语言编程,学生学籍信息管理系统C语言设计.doc

    学生学籍信息管理系统C语言设计 学生学籍信息管理系统 目录 1.设计目的与要求 2.总体设计 3.详细设计 4.调试分析 5.总结 6.答辩记录 7.教师意见 8.附录主程序 1.设计目的与要求: 1 ...

  5. 基于python+tkinter的学生成绩信息管理系统

    基于python+tkinter的学生成绩信息管理系统 系统设计 2.开发工具 开发语言:python3.6.8 开发工具:JetBrains PyCharm 2019.1.2 x64 使用三方模块: ...

  6. 基于JavaWeb学生成绩信息管理系统(附源码资料)-毕业设计

    1. 适用人群 本课程主要是针对计算机专业相关正在做毕业设计.或者是需要实战项目的Java开发学习者. 2. 你将收获 提供:项目源码.项目文档.数据库脚本.软件工具等所有资料(在平台的课程附件中进行 ...

  7. 【基于SSM+MySQL+Jsp的高校学生成绩信息管理系统的设计与实现 ---(效果+源代码+数据库+获取 ~ ~】

    快速阅读目录 写在前面: (一)效果展示 (1)数据库表一览 (2)部分运行截图 (二)代码展示 (三)说明 写在前面: tips:这是一个基于SSM+MySQL+Jsp等技术的高校学生成绩信息管理系 ...

  8. C#程序代码连接SQL Server数据库实现学生成绩信息管理系统(重置版)

    目录 一.创建数据库表和配置SQL数据库连接信息 1.创建数据库表 2.配置数据库连接信息 二.配置程序代码 1.StudentAccount类 2.Student类 3.TeacherAccount ...

  9. C语言学生成绩信息管理系统课程设计报告

    C语言课程设计报告 一 .设计目的 学生成绩管理系统 主要功能: (1)能按学期.按班级完成对学生成绩的录入. 修改,删除 (2)能按班级统计学生的成绩,求学生的总分及 平均分,并能根据学生的平均成绩 ...

最新文章

  1. 公平锁与非公平锁源码对比
  2. 分享一个自用的,随便找到的组件,留作记录
  3. osg中三维模型的位置变换
  4. 获取ClassLoader的途径
  5. C语言变量的类型和存储位置
  6. 二维码研究综述--传统图像处理方法
  7. html图片加滚动文字,滚动文字、图片等html代码
  8. 4.5_abstract_factory_创建型模式:抽象工厂模式
  9. easyui 控制某列显示不显示_实验八 LED数码管显示控制实验
  10. spark中local模式与cluster模式使用场景_详细总结spark基于standalone、yarn集群提交作业流程...
  11. 【旧文章搬运】深入分析Win7的对象引用跟踪机制
  12. 学习笔记(10):每一道试题都是有解题密码(2018年下半年信息系统项目管理师试题讲解)-用这种简单方法破解这么难的试题,我也是醉了(试题21-25)...
  13. 锂电池的充电原理以及快充原理
  14. 华为手机usb调试已打开,adb devices不显示设备
  15. 如何将win7电脑变身WIFI热点,让手机、笔记本共享上网?
  16. Dingo Api请求接口404?
  17. 订单信息表和订单明细表
  18. riak mysql_[Translate] 从SQL数据库迁移到Riak
  19. Portal服务器开源无线,OpenPortalServer开源Portal服务 Web认证服务器 支持华为 H3C 锐捷设备...
  20. MLDonkey命令手册

热门文章

  1. [渝粤教育] 长春中医药大学 药事管理与法规 参考 资料
  2. 使用Socks5代理保障Windows网络安全
  3. 计算机切换输入法Word关闭,电脑office编辑文字输入法快捷键不能切换怎么办
  4. 数据中台夯实数据基础
  5. mac使用php无法写入文件,mac移动硬盘无法写入怎么办
  6. 超声波传感器与液晶屏显示实验
  7. YGG SEA与Solana Ventures达成合作,为东南亚的游戏开发注入活力
  8. Node.js轻量级Web框架Express4.x使用指南
  9. OCM Examination Guide
  10. NCH PicoPDF Plus for Mac(PDF编辑器)