找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 2333|回复: 4

【C】学生成绩管理系统

[复制链接]
发表于 2021-4-13 00:07:23 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
这是用C写的学生成绩管理系统,需要StoneValley库的支持。
本程序可以给读者做个参考。
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <float.h>
  5. #include "StoneValley-master/src/svstring.h"

  6. static const char * db_filename = "stu_database.dat";

  7. typedef struct tag_StudentInfo
  8. {
  9.         int id;
  10.         char name[16];
  11.         float chinese;
  12.         float math;
  13.         float english;
  14. } StudentInfo, * PStudentInfo;

  15. ARRAY_Z g_db = { 0 }; // Data base.

  16. // Input students' credits.
  17. void InputDegrees(PStudentInfo pinfo)
  18. {
  19.         int i;
  20.         do
  21.         {
  22.                 printf("Input student ID:%d. %s's credits by class.\n\t[1].Chinese.\n\t[2].Math\n\t[3].English\n\t[0].Return to upper menu.\n? ", pinfo->id, pinfo->name);
  23.                 scanf_s("%d", &i);
  24.                 switch (i)
  25.                 {
  26.                 case 1:
  27.                         printf("Chinese:? ");
  28.                         scanf_s("%f", &pinfo->chinese);
  29.                         break;
  30.                 case 2:
  31.                         printf("Math:? ");
  32.                         scanf_s("%f", &pinfo->math);
  33.                         break;
  34.                 case 3:
  35.                         printf("English:? ");
  36.                         scanf_s("%f", &pinfo->english);
  37.                         break;
  38.                 }
  39.         } while (i);
  40. }

  41. int LinearSearchDBByID(void * pitem, size_t param)
  42. {
  43.         if (((PStudentInfo)pitem)->id == (int)0[((size_t *)param)])
  44.                 return CBF_TERMINATE;
  45.         ++1[((size_t *)param)];
  46.         return CBF_CONTINUE;
  47. }

  48. void InputStudentIDAndName(PStudentInfo pinfo)
  49. {
  50.         size_t a[2];
  51.         StudentInfo infot = { 0 };
  52.         printf("Input student ID and name.\n");
  53. Lbl_Input_ID:
  54.         printf("Student ID:? ");
  55.         scanf_s("%d", &infot.id);
  56.         a[0] = infot.id;
  57.         a[1] = 0;
  58.         if (CBF_TERMINATE == strTraverseArrayZ(&g_db, sizeof infot, LinearSearchDBByID, (size_t)a, FALSE))
  59.         {
  60.                 printf("Student ID should be unique.\n");
  61.                 goto Lbl_Input_ID;
  62.         }
  63.         printf("Student name:? ");
  64.         scanf_s("%s", infot.name, 15);
  65.         memcpy(pinfo, &infot, sizeof infot);
  66. }

  67. void PrintStudentInfo(PStudentInfo pinfo)
  68. {
  69.         printf("%d\t%s\t%.2f\t%.2f\t%.2f\n", pinfo->id, pinfo->name, pinfo->chinese, pinfo->math, pinfo->english);
  70. }

  71. PStudentInfo FindStudentByID(int id)
  72. {
  73.         size_t a[2];
  74.         a[0] = id;
  75.         a[1] = 0;
  76.         if (CBF_TERMINATE == strTraverseArrayZ(&g_db, sizeof(StudentInfo), LinearSearchDBByID, (size_t)a, FALSE))
  77.                 return strLocateItemArrayZ(&g_db, sizeof(StudentInfo), a[1]);
  78.         return NULL;
  79. }

  80. int LinearSearchDBByName(void * pitem, size_t param)
  81. {
  82.         if (strcmp(((PStudentInfo)pitem)->name, (const char *)0[((size_t *)param)]) == 0)
  83.         {
  84.                 PrintStudentInfo(pitem);
  85.                 ++1[((size_t *)param)];
  86.         }
  87.         return CBF_CONTINUE;
  88. }

  89. int LinearSearchDBByScore(void * pitem, size_t param)
  90. {
  91.         float x, y, z;
  92.         x = *(float *)0[((size_t *)param)];
  93.         y = *(float *)1[((size_t *)param)];

  94.         switch (3[((size_t *)param)])
  95.         {
  96.         case 3: // Chinese.
  97.                 z = ((PStudentInfo)pitem)->chinese;
  98.                 if (z >= x && z <= y)
  99.                 {
  100.                         PrintStudentInfo(pitem);
  101.                         ++2[((size_t *)param)];
  102.                 }
  103.                 break;
  104.         case 4: // Math.
  105.                 z = ((PStudentInfo)pitem)->math;
  106.                 if (z >= x && z <= y)
  107.                 {
  108.                         PrintStudentInfo(pitem);
  109.                         ++2[((size_t *)param)];
  110.                 }
  111.                 break;
  112.         case 5: // English.
  113.                 z = ((PStudentInfo)pitem)->english;
  114.                 if (z >= x && z <= y)
  115.                 {
  116.                         PrintStudentInfo(pitem);
  117.                         ++2[((size_t *)param)];
  118.                 }
  119.                 break;
  120.         }
  121.         return CBF_CONTINUE;
  122. }

  123. void FindStudent(void)
  124. {
  125.         size_t a[4];
  126.         int i, id;
  127.         char buffer[16] = { 0 };
  128.         PStudentInfo pinfo;
  129.         float x, y;
  130.         do
  131.         {
  132.                 printf("Find student.\n\t[1].By ID.\n\t[2].By name.\n\t[3].By Chinese score.\n\t[4].By Math score.\n\t[5].By English score.\n\t[0].Return to upper menu.\n? ");
  133.                 scanf_s("%d", &i);
  134.                 switch (i)
  135.                 {
  136.                 case 1:
  137.                         printf("Input student ID:? ");
  138.                         scanf_s("%d", &id);
  139.                         pinfo = FindStudentByID(id);
  140.                         if (pinfo)
  141.                         {
  142.                                 printf("ID\tName\tChinese\tMath\tEnglish\n");
  143.                                 PrintStudentInfo(pinfo);
  144.                         }
  145.                         else
  146.                                 printf("Can not find student ID:%d.\n", id);
  147.                         break;
  148.                 case 2:
  149.                         printf("Input student name:? ");
  150.                         scanf_s("%s", buffer, 15);
  151.                         a[0] = (size_t)buffer;
  152.                         a[1] = 0;
  153.                         printf("ID\tName\tChinese\tMath\tEnglish\n");
  154.                         strTraverseArrayZ(&g_db, sizeof(StudentInfo), LinearSearchDBByName, (size_t)a, FALSE);
  155.                         printf("%zd student(s) found.\n", a[1]);
  156.                         break;
  157.                 case 3:
  158.                 case 4:
  159.                 case 5:
  160.                         printf("Input lower bound for score:[x,y] x? ");
  161.                         scanf_s("%f", &x);
  162.                         printf("Input upper bound for score:[x,y] y? ");
  163.                         scanf_s("%f", &y);
  164.                         a[0] = (size_t)&x;
  165.                         a[1] = (size_t)&y;
  166.                         a[2] = 0;
  167.                         a[3] = i;
  168.                         printf("ID\tName\tChinese\tMath\tEnglish\n");
  169.                         strTraverseArrayZ(&g_db, sizeof(StudentInfo), LinearSearchDBByScore, (size_t)a, FALSE);
  170.                         printf("%zd student(s) found.\n", a[2]);
  171.                         break;
  172.                 }
  173.         } while (i);
  174. }

  175. int ListStudentsInfo(void * pitem, size_t param)
  176. {
  177.         PrintStudentInfo(pitem);
  178.         ++0[((size_t *)param)];
  179.         return CBF_CONTINUE;
  180. }

  181. int cmp_student_id(const void * px, const void * py)
  182. {
  183.         return ((PStudentInfo)px)->id - ((PStudentInfo)py)->id;
  184. }

  185. int cmp_student_name(const void * px, const void * py)
  186. {
  187.         return strcmp(((PStudentInfo)px)->name, ((PStudentInfo)py)->name);
  188. }

  189. int cmp_student_chinese(const void * px, const void * py)
  190. {
  191. #define CLASS chinese
  192.         if (((PStudentInfo)px)->CLASS > ((PStudentInfo)py)->CLASS)
  193.                 return 1;
  194.         else if (((PStudentInfo)px)->CLASS < ((PStudentInfo)py)->CLASS)
  195.                 return -1;
  196.         return 0;
  197. #undef CLASS
  198. }

  199. int cmp_student_math(const void * px, const void * py)
  200. {
  201. #define CLASS math
  202.         if (((PStudentInfo)px)->CLASS > ((PStudentInfo)py)->CLASS)
  203.                 return 1;
  204.         else if (((PStudentInfo)px)->CLASS < ((PStudentInfo)py)->CLASS)
  205.                 return -1;
  206.         return 0;
  207. #undef CLASS
  208. }

  209. int cmp_student_english(const void * px, const void * py)
  210. {
  211. #define CLASS english
  212.         if (((PStudentInfo)px)->CLASS > ((PStudentInfo)py)->CLASS)
  213.                 return 1;
  214.         else if (((PStudentInfo)px)->CLASS < ((PStudentInfo)py)->CLASS)
  215.                 return -1;
  216.         return 0;
  217. #undef CLASS
  218. }

  219. int cmp_student_total(const void * px, const void * py)
  220. {
  221.         float x, y;
  222.         x = ((PStudentInfo)px)->chinese + ((PStudentInfo)px)->math + ((PStudentInfo)px)->english;
  223.         y = ((PStudentInfo)py)->chinese + ((PStudentInfo)py)->math + ((PStudentInfo)py)->english;
  224.         if (x > y)
  225.                 return 1;
  226.         else if (x < y)
  227.                 return -1;
  228.         return 0;
  229. }

  230. void SortStudentInfo(void)
  231. {
  232.         int i;
  233.         size_t a[2] = { 0 };
  234.         do
  235.         {
  236.                 printf("Sort student information.\n\t[1].Sort student by ID.\n\t[2].Sort students by name.\n\t[3].Sort students Chinese score.\n\t[4].Sort students by Math score.\n\t[5].Sort students by English score.\n\t[6].Sort students by total score.\n\t[0].Return to upper menu.\n? ");
  237.                 scanf_s("%d", &i);
  238.                 switch (i)
  239.                 {
  240.                 case 1: // By ID.
  241.                         strSortArrayZ(&g_db, sizeof(StudentInfo), cmp_student_id);
  242.                         break;
  243.                 case 2: // By name.
  244.                         strSortArrayZ(&g_db, sizeof(StudentInfo), cmp_student_name);
  245.                         break;
  246.                 case 3: // By Chinese.
  247.                         strSortArrayZ(&g_db, sizeof(StudentInfo), cmp_student_chinese);
  248.                         break;
  249.                 case 4: // By Math.
  250.                         strSortArrayZ(&g_db, sizeof(StudentInfo), cmp_student_math);
  251.                         break;
  252.                 case 5: // By English.
  253.                         strSortArrayZ(&g_db, sizeof(StudentInfo), cmp_student_english);
  254.                         break;
  255.                 case 6: // By total score.
  256.                         strSortArrayZ(&g_db, sizeof(StudentInfo), cmp_student_total);
  257.                         break;
  258.                 }
  259.                 a[0] = 0;
  260.                 printf("ID\tName\tChinese\tMath\tEnglish\n");
  261.                 strTraverseArrayZ(&g_db, sizeof(StudentInfo), ListStudentsInfo, (size_t)a, FALSE);
  262.                 printf("%zd student(s) enlisted.\n", a[0]);
  263.         } while (i);
  264. }

  265. int ComputeStatistics(void * pitem, size_t param)
  266. {
  267.         PStudentInfo pinfo = (PStudentInfo)pitem;
  268.         float * chinese_total = (float *)0[(size_t *)param];
  269.         float * chinese_max   = (float *)1[(size_t *)param];
  270.         float * chinese_min   = (float *)2[(size_t *)param];
  271.         float * math_total    = (float *)3[(size_t *)param];
  272.         float * math_max      = (float *)4[(size_t *)param];
  273.         float * math_min      = (float *)5[(size_t *)param];
  274.         float * english_total = (float *)6[(size_t *)param];
  275.         float * english_max   = (float *)7[(size_t *)param];
  276.         float * english_min   = (float *)8[(size_t *)param];

  277.         (*chinese_total) += pinfo->chinese;
  278.         (*math_total) += pinfo->math;
  279.         (*english_total) += pinfo->english;
  280.        
  281.         if (*chinese_max < pinfo->chinese)
  282.                 *chinese_max = pinfo->chinese;
  283.         if (*math_max < pinfo->math)
  284.                 *math_max = pinfo->math;
  285.         if (*english_max < pinfo->english)
  286.                 *english_max = pinfo->english;
  287.        
  288.         if (*chinese_min > pinfo->chinese)
  289.                 *chinese_min = pinfo->chinese;
  290.         if (*math_min > pinfo->math)
  291.                 *math_min = pinfo->math;
  292.         if (*english_min > pinfo->english)
  293.                 *english_min = pinfo->english;

  294.         ++9[(size_t *)param];
  295.         return CBF_CONTINUE;
  296. }

  297. void Statistics(void)
  298. {
  299.         int i;
  300.         float f[10] = { 0.0 };
  301.         size_t a[10];
  302.         f[2] = f[5] = f[8] = FLT_MAX;
  303.         f[1] = f[4] = f[7] = FLT_MIN;
  304.         for (i = 0; i < 9; ++i)
  305.                 a[i] = (size_t)(f + i);
  306.         a[9] = 0;
  307.         printf("Statistics for average, maximum and minimum score of three classes:\n");
  308.         strTraverseArrayZ(&g_db, sizeof(StudentInfo), ComputeStatistics, (size_t)a, FALSE);
  309.         printf("Chinese:\n\tAvg\tMax\tMin\n\t%0.2f\t%0.2f\t%0.2f\n", f[0] / (float)a[9], f[1], f[2]);
  310.         printf("Math:\n\tAvg\tMax\tMin\n\t%0.2f\t%0.2f\t%0.2f\n",    f[3] / (float)a[9], f[4], f[5]);
  311.         printf("English:\n\tAvg\tMax\tMin\n\t%0.2f\t%0.2f\t%0.2f\n", f[6] / (float)a[9], f[7], f[8]);
  312. }

  313. void ReadDataBaseFile(void)
  314. {
  315.         StudentInfo si;
  316.         FILE * fp;
  317.         fopen_s(&fp, db_filename, "rb");
  318.         if (fp)
  319.         {
  320.                 while (!feof(fp))
  321.                 {
  322.                         fread(&si, sizeof si, 1, fp);
  323.                         if (!feof(fp))
  324.                                 if (strResizeArrayZ(&g_db, strLevelArrayZ(&g_db) + 1, sizeof si))
  325.                                         strInsertItemArrayZ(&g_db, &si, sizeof si, strLevelArrayZ(&g_db) - 1);
  326.                 }
  327.                 fclose(fp);
  328.         }
  329. }

  330. int CBFWriteDataBase(void * pitem, size_t param)
  331. {
  332.         fwrite(pitem, sizeof(StudentInfo), 1, (FILE *)param);
  333.         return CBF_CONTINUE;
  334. }

  335. void WriteDataBaseFile(void)
  336. {
  337.         FILE * fp;
  338.         fopen_s(&fp, db_filename, "wb");
  339.         if (fp)
  340.         {
  341.                 strTraverseArrayZ(&g_db, sizeof(StudentInfo), CBFWriteDataBase, (size_t)fp, FALSE);
  342.                 fclose(fp);
  343.         }
  344. }

  345. int main(void)
  346. {
  347.         int i, id;
  348.         size_t a[2];
  349.         StudentInfo si = { 0 }, * pinfo;
  350.         ReadDataBaseFile();
  351.         do
  352.         {
  353.                 printf("Student Information Management System v%s.\n", LIB_VER);
  354.                 printf("[1].Insert student.\n");
  355.                 printf("[2].Remove student.\n");
  356.                 printf("[3].List all students.\n");
  357.                 printf("[4].Find student.\n");
  358.                 printf("[5].Alter student's information.\n");
  359.                 printf("[6].Sort student information.\n");
  360.                 printf("[7].Statistics.\n");
  361.                 printf("[0].Exit.\n? ");
  362.                 scanf_s("%d", &i);
  363.                 switch (i)
  364.                 {
  365.                 case 1:
  366.                         InputStudentIDAndName(&si);
  367.                         InputDegrees(&si);
  368.                         if (strResizeArrayZ(&g_db, strLevelArrayZ(&g_db) + 1, sizeof si) && strInsertItemArrayZ(&g_db, &si, sizeof si, strLevelArrayZ(&g_db) - 1))
  369.                         {
  370.                                 printf("Insertion succeeded!\n");
  371.                                 PrintStudentInfo(&si);
  372.                         }
  373.                         else
  374.                                 printf("Insertion failed!\n");
  375.                         break;
  376.                 case 2:
  377.                         printf("Input student ID:? ");
  378.                         scanf_s("%d", &id);
  379.                         a[0] = id;
  380.                         a[1] = 0;
  381.                         if (CBF_TERMINATE == strTraverseArrayZ(&g_db, sizeof(StudentInfo), LinearSearchDBByID, (size_t)a, FALSE))
  382.                         {
  383.                                 strRemoveItemArrayZ(&g_db, sizeof si, a[1], TRUE);
  384.                                 printf("Student information has been deleted!\n");
  385.                         }
  386.                         else
  387.                                 printf("Can not find student ID:%d.\n", id);
  388.                         break;
  389.                 case 3:
  390.                         a[0] = 0;
  391.                         printf("ID\tName\tChinese\tMath\tEnglish\n");
  392.                         strTraverseArrayZ(&g_db, sizeof(StudentInfo), ListStudentsInfo, (size_t)a, FALSE);
  393.                         printf("%zd student(s) enlisted.\n", a[0]);
  394.                         break;
  395.                 case 4:
  396.                         FindStudent();
  397.                         break;
  398.                 case 5:
  399.                         printf("Input student ID:? ");
  400.                         scanf_s("%d", &id);
  401.                         a[0] = id;
  402.                         a[1] = 0;
  403.                         if (CBF_TERMINATE == strTraverseArrayZ(&g_db, sizeof(StudentInfo), LinearSearchDBByID, (size_t)a, FALSE))
  404.                         {
  405.                                 pinfo = (PStudentInfo)strLocateItemArrayZ(&g_db, sizeof si, a[1]);
  406.                                 InputStudentIDAndName(pinfo);
  407.                                 InputDegrees(pinfo);
  408.                                 printf("Student information has been successfully altered!\n");
  409.                         }
  410.                         else
  411.                                 printf("Can not find student ID:%d.\n", id);
  412.                         break;
  413.                 case 6:
  414.                         SortStudentInfo();
  415.                         break;
  416.                 case 7:
  417.                         Statistics();
  418.                         break;
  419.                 }
  420.         } while (i);
  421.         WriteDataBaseFile();
  422.         PrintStudentInfo(&si);
  423.         strFreeArrayZ(&g_db);
  424.         return 0;
  425. }
复制代码

运行结果如下:
111Capture.PNG
回复

使用道具 举报

发表于 2021-4-15 14:19:21 | 显示全部楼层
感觉只需要把strTraverseArrayZ这个函数自己实现一下就可以不用依赖StoneValley库了。

++0[((size_t *)param)]可还行。
回复 赞! 靠!

使用道具 举报

发表于 2021-4-18 18:53:41 | 显示全部楼层
0xAA55 发表于 2021-4-15 14:19
感觉只需要把strTraverseArrayZ这个函数自己实现一下就可以不用依赖StoneValley库了。

++0[((size_t *)par ...

哈哈哈太草了,这个只能忽悠C语言初学者吧!
回复 赞! 靠!

使用道具 举报

发表于 2021-9-1 12:38:36 | 显示全部楼层
0xAA55 发表于 2021-4-15 14:19
感觉只需要把strTraverseArrayZ这个函数自己实现一下就可以不用依赖StoneValley库了。

++0[((size_t *)par ...

不行,还有strSortArrayZ和strResizeArrayZ等函数是库里的。这些函数支持定长数组组件的工作。
((size_t *)param)[0]++;
*((size_t *)param)++;
也行。
回复 赞! 靠!

使用道具 举报

发表于 2021-9-1 12:40:38 | 显示全部楼层
watermelon 发表于 2021-4-18 18:53
哈哈哈太草了,这个只能忽悠C语言初学者吧!


有些时候++0[((size_t *)param)]这种写法比其他写法容易查看。
比如这种模式下:
  1.     float * chinese_total = (float *)0[(size_t *)param];
  2.     float * chinese_max   = (float *)1[(size_t *)param];
  3.     float * chinese_min   = (float *)2[(size_t *)param];
  4.     float * math_total    = (float *)3[(size_t *)param];
  5.     float * math_max      = (float *)4[(size_t *)param];
  6.     float * math_min      = (float *)5[(size_t *)param];
  7.     float * english_total = (float *)6[(size_t *)param];
  8.     float * english_max   = (float *)7[(size_t *)param];
  9.     float * english_min   = (float *)8[(size_t *)param];
复制代码

这种写法会容易查看并且很整齐。
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-11-23 17:44 , Processed in 0.035353 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表