• 学生管理系统(C语言)


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 #define N 3
      5 #define LEN (Student*) malloc(sizeof(Student))
      6 /* 学生数据结构 */
      7 typedef struct node
      8 {
      9     char num[20];
     10     char name[15];
     11     int score[N];
     12     int sum;
     13     double ave;
     14     struct node *next;
     15 } Student;
     16  
     17 /* 头指针 */
     18 Student *head = NULL;
     19 /* 临时指针 */
     20 Student *tmp = NULL;
     21 /* 课程名称 */
     22 char CLASSNAME[N][30] = {"大物", "高数", "c语言"};
     23 /* 命令开关 */
     24 int SWITCH[16] = {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
     25 /* 函数声明 */
     26 int Menu();
     27 Student* Init();
     28 int CheckNUM(char*);
     29 int CheckName(char*);
     30 int CheakScore(int score);
     31 int Same_NUM(char*);
     32 void InputNodeInfo(Student*);
     33 void OutputNodeInfo(Student*);
     34 Student* SearchFrontNode(Student*);
     35 void DeleteNode(Student*);
     36 void InsertBefore();
     37 void InputList();
     38 Student* SearchID(char*);
     39 Student* SearchName(char*);
     40 void SearchDeleteNode();
     41 void OutList();
     42 void SearchPrintNode();
     43 void Compute();
     44 int CmpID(Student*, Student*, int);
     45 int CmpSum(Student*, Student*, int);
     46 int CmpScore(Student*, Student*, int);
     47 Student* SearchMaxNode(int (*cmp)(Student*, Student*, int), int);
     48 Student* Sort(int (*cmp)(Student*, Student*, int), int);
     49 void OutputToFile(FILE*, Student*, int);
     50 void InsertAfter(Student*);
     51 void SaveToFile();
     52 void LoadFile();
     53 void CopyFile();
     54 void InsertToFile();
     55 void FreeList(Student* p);
     56 void Stat();
     57 void Quit();
     58  
     59 /* 主函数 */
     60 int main()
     61 {
     62     int n;
     63  
     64     while (1)
     65     {
     66         n = Menu();
     67         {
     68             if (n == 1 || n == 15 || SWITCH[1])
     69             {
     70                 switch (n)
     71                 {
     72                         /* 执行初始化 */
     73                     case 1:
     74                         head = Init();
     75                         printf("LOOK...初始化成功
    ");
     76                         break;
     77                         /* 创建链表 ,输入学生信息*/
     78                     case 2:
     79                         InputList();
     80                         break;
     81                         /* 查找学号或姓名删除信息 */
     82                     case 3:
     83                         SearchDeleteNode();
     84                         break;
     85                         /* 输出全部学生信息 */
     86                     case 4:
     87                         system("cls");
     88                         OutList();
     89                         break;
     90                         /* 按姓名查找学生信息*/
     91                     case 5:
     92                         SearchPrintNode();
     93                         break;
     94                         /* 保存到文件 */
     95                     case 6:
     96                         SaveToFile();
     97                         break;
     98                         /* 从文件中读取学生信息*/
     99                     case 7:
    100                         if (SWITCH[6])
    101                         {
    102                             head = Init();
    103                             LoadFile();
    104                         }
    105                         else
    106                         {
    107                             printf("当前文件未保存
    ");
    108                         }
    109                         break;
    110                         /* 计算所有学生的总分和平均分 */
    111                     case 8:
    112                         Compute();
    113                         SWITCH[8] = 1;
    114                         printf("计算完毕
    ");
    115                         break;
    116                         /* 插入一个学生信息到链表 */
    117                     case 9:
    118                         InsertBefore();
    119                         SWITCH[6] = 0;
    120                         SWITCH[8] = 0;
    121                         break;
    122                         /* 复制文件 */
    123                     case 10:
    124                         CopyFile();
    125                         break;
    126                         /* 排序,按总分排序并打印学生信息 */
    127                     case 11:
    128                         if (SWITCH[8])
    129                         {
    130                             head = Sort(CmpSum, 0);
    131                             system("cls");
    132                             OutList();
    133                         }
    134                         else
    135                         {
    136                             printf("请先计算总分!
    ");
    137                         }
    138                         break;
    139                         /* 尾部添加一个学生信息到文件中 */
    140                     case 12:
    141                         InsertToFile();
    142                         SWITCH[6] = 0;
    143                         printf("尾部添加完毕!
    ");
    144                         break;
    145                         /* 按学号搜索..学生信息*/
    146                     case 13:
    147                         if (SWITCH[8])
    148                         {
    149                             head = Sort(CmpID, 0);
    150                             system("cls");
    151                             OutList();
    152                         }
    153                         else
    154                         {
    155                             printf("请先计算总分!
    ");
    156                         }
    157                         break;
    158                         /* 分类汇总 */
    159                     case 14:
    160                         system("cls");
    161                         Stat();
    162                         break;
    163                         /* 结束 */
    164                     case 15:
    165                         Quit();
    166                         break;
    167                     default:
    168                         printf("无效命令!
    ");
    169                         fflush(stdin);
    170                 }
    171                 system("pause");
    172             }
    173             else
    174             {
    175                 printf("你必须首先初始化!
    ");
    176                 system("pause");
    177             }
    178         }
    179     }
    180  
    181     system("pause");
    182     return 0;
    183 }
    184  
    185 /* 菜单 */
    186 int Menu()
    187 {
    188     int n;
    189     system("cls");
    190     fflush(stdin);
    191     printf("*********************************************************************
    ");
    192     printf("*********************************************************************
    ");
    193     printf("【01】 初始化........
    ");
    194     printf("【02】 输入学生信息
    ");
    195     printf("【03】 查找学号或姓名删除信息
    ");
    196     printf("【04】 输出全部学生信息
    ");
    197     printf("【05】 按姓名查找学生信息
    ");
    198     printf("【06】 保存到文件
    ");
    199     printf("【07】 从文件中读取学生信息
    ");
    200     printf("【08】 计算所有学生的总分和平均分
    ");
    201     printf("【09】 插入一个学生信息到链表中
    ");
    202     printf("【10】 复制文件
    ");
    203     printf("【11】 按总分排序并打印学生信息
    ");
    204     printf("【12】 尾部添加一个学生信息到文件中
    ");
    205     printf("【13】 按学号搜索..学生信息
    ");
    206     printf("【14】 分类汇总
    ");
    207     printf("【15】 退出
    ");
    208     printf("********************************************************************
    ");
    209     printf("请输入命令编号: ");
    210     scanf("%d", &n);
    211     return n;
    212 }
    213  
    214 /* 初始化 */
    215 Student* Init()
    216 {
    217     int i;
    218     Student *head;
    219     head = LEN;
    220     head->next = NULL;
    221  
    222     /* 命令开关初始化 */
    223     for (i = 1; i < 16; i++)
    224     {
    225         SWITCH[i] = 0;
    226     }
    227  
    228     SWITCH[1] = 1;
    229     SWITCH[6] = 1;
    230     return head;
    231 }
    232  
    233 /* 检查学号 */
    234 int CheckNUM(char* s)
    235 {
    236     int i;
    237  
    238     if (strlen(s) == 0 || strlen(s) > 10) return 0;
    239  
    240     for (i = 0; i < strlen(s); i++)
    241     {
    242         if (s[i] < '0' || s[i] > '9') return 0;
    243     }
    244  
    245     return 1;
    246 }
    247  
    248 /* 检查姓名 */
    249 int CheckName(char* s)
    250 {
    251     int i;
    252  
    253     if (strlen(s) == 0 || strlen(s) > 15) return 0;
    254  
    255     for (i = 0; i < strlen(s); i++)
    256     {
    257         if (!(s[i] >= 'a' && s[i] <= 'z' || s[i] >= 'A' && s[i] <= 'Z')) return 0;
    258     }
    259  
    260     return 1;
    261 }
    262  
    263 /* 检查分数 */
    264 int CheakScore(int score)
    265 {
    266     if (score > 100 || score <= 0) return 0;
    267     return 1;
    268 }
    269  
    270 /* 检查相同学号 */
    271 int Same_NUM(char* s)
    272 {
    273     Student *p = head->next;
    274     while(p != NULL)
    275     {
    276         if (strcmp(s, p->num) == 0) return 1;
    277         p = p->next;
    278     }
    279     return 0;
    280 }
    281  
    282 /* 给p指向的节点输入信息 */
    283 void InputNodeInfo(Student* p)
    284 {
    285     fflush(stdin);
    286  
    287     /* 学号 */
    288     printf("
    请输入学号: ");
    289     do
    290     {
    291         gets(p->num);
    292  
    293         if (!CheckNUM(p->num))
    294         {
    295             printf("数据不标准,请重新输入学号: ");
    296         }
    297         else if (Same_NUM(p->num))
    298         {
    299             printf("检测到此学号存在,请重新输入: ");
    300         }
    301     }while (!(CheckNUM(p->num) && !Same_NUM(p->num)));
    302  
    303     /* 姓名 */
    304     printf("请输入姓名: ");
    305     do
    306     {
    307         gets(p->name);
    308          if (!CheckName(p->name))
    309         {
    310             printf("数据不标准,请重新输入姓名: ");
    311         }
    312     }
    313     while (!CheckName(p->name));
    314  
    315     /* 成绩 */
    316     int i;
    317     for (i = 0; i < N; i++)
    318     {
    319         printf("请输入 %s 成绩: ", CLASSNAME[i]);
    320         do
    321         {
    322             fflush(stdin);
    323             scanf("%d", &p->score[i]);
    324  
    325             if (!CheakScore(p->score[i]))
    326             {
    327                 printf("数据不标准,请重新输入 %s 成绩: ", CLASSNAME[i]);
    328             }
    329         }
    330         while (!CheakScore(p->score[i]));
    331     }
    332  
    333     /* 总分及平均分 */
    334     p->sum = -1;
    335     p->ave = -1;
    336 }
    337  
    338 /* 输出p指向节点的信息 */
    339 void OutputNodeInfo(Student* p)
    340 {
    341     int i;
    342     printf("
    ");
    343     printf("姓名: %s
    ", p->name);
    344     printf("学号: %s
    ", p->num);
    345  
    346     for (i = 0; i < N; i++)
    347     {
    348         printf("%s 成绩: %d
    ", CLASSNAME[i], p->score[i]);
    349     }
    350  
    351     /* 计算过才输出 */
    352     if (SWITCH[8]) printf("总分: %d
    ", p->sum);
    353     if (SWITCH[8]) printf("平均分: %.2lf
    ", p->ave);
    354 }
    355  
    356 /* 返回r的前一个节点 */
    357 Student* SearchFrontNode(Student* r)
    358 {
    359     Student *p = head;
    360     while (p->next != r) p = p->next;
    361     return p;
    362 }
    363  
    364 /* 删除r指向的节点 */
    365 void DeleteNode(Student* r)
    366 {
    367     Student *p = SearchFrontNode(r);
    368     p->next = r->next;
    369 }
    370  
    371 /* 头插法插入节点 */
    372 void InsertBefore()
    373 {
    374     Student *s = LEN;
    375     InputNodeInfo(s);
    376     s->next = head->next;
    377     head->next = s;
    378 }
    379  
    380 /* 输入链表 */
    381 void InputList()
    382 {
    383     int n;
    384     printf("有多少个学生信息要输入? ");
    385     scanf("%d", &n);
    386  
    387     while (n--)
    388     {
    389         InsertBefore();
    390     }
    391 }
    392  
    393 /* 按学号查找 */
    394 Student* SearchID(char* num)
    395 {
    396     Student *p = head->next;
    397  
    398     while (p != NULL)
    399     {
    400         if (strcmp(p->num, num) == 0) break;
    401         p = p->next;
    402     }
    403  
    404     return p;
    405 }
    406  
    407 /* 按姓名查找 */
    408 Student* SearchName(char* name)
    409 {
    410     Student *p = head->next;
    411  
    412     while (p != NULL)
    413     {
    414         if (strcmp(p->name, name) == 0) break;
    415         p = p->next;
    416     }
    417  
    418     return p;
    419 }
    420  
    421 /* 按学号或姓名查找删除节点 */
    422 void SearchDeleteNode()
    423 {
    424     Student *p;
    425     fflush(stdin);
    426     char str[20];
    427     char sure[20];
    428  
    429     /* 输入合法性判断 */
    430     printf("请输入你要删除的学生的 姓名 或 学号: ");
    431     do
    432     {
    433         gets(str);
    434  
    435         if (!(CheckNUM(str) || CheckName(str)))
    436         {
    437             printf("数据不标准,请重新输入姓名或学号: ");
    438         }
    439     }
    440     while (!(CheckNUM(str) || CheckName(str)));
    441  
    442     /* 判断是姓名还是学号 */
    443     if (str[0] >= '0' && str[0] <= '9')
    444     {
    445         p = SearchID(str);
    446  
    447         if (p == NULL)
    448         {
    449             printf("对不起,找不到这个学号
    ");
    450         }
    451         else
    452         {
    453             OutputNodeInfo(p);
    454             printf("确认删除? (输入"y"确认,任意键取消): ");
    455             if (strcmp(gets(sure), "y") == 0)
    456             {
    457                 DeleteNode(p);
    458                 printf("删除成功
    ");
    459                 SWITCH[6] = 0;
    460             }
    461             fflush(stdin);
    462         }
    463     }
    464     else
    465     {
    466         p = SearchName(str);
    467  
    468         if (p == NULL)
    469         {
    470             printf("对不起,找不到这个姓名
    ");
    471         }
    472         else
    473         {
    474             OutputNodeInfo(p);
    475             printf("确认删除? (输入"y"确认,任意键取消): ");
    476             if (strcmp(gets(sure), "y") == 0)
    477             {
    478                 DeleteNode(p);
    479                 printf("删除成功!
    ");
    480                 SWITCH[6] = 0;
    481              }
    482             fflush(stdin);
    483         }
    484     }
    485 }
    486  
    487 /* 输出链表 */
    488 void OutList()
    489 {
    490     Student *p = head->next;
    491  
    492     /* 空表处理 */
    493     if (p == NULL)
    494     {
    495         printf("暂无学生信息!
    ");
    496     }
    497  
    498     while (p != NULL)
    499     {
    500         OutputNodeInfo(p);
    501         p = p->next;
    502     }
    503 }
    504  
    505 /* 按姓名查找记录并打印 */
    506 void SearchPrintNode()
    507 {
    508     Student *p = head->next;
    509     int ok = 1; 
    510     char name[20];
    511     fflush(stdin);
    512  
    513     /* 姓名合法性判断 */
    514     printf("请输入你要查找的学生姓名: ");
    515     do
    516     {
    517         gets(name);
    518  
    519         if (!CheckName(name))
    520         {
    521             printf("数据不标准,请重新输入姓名: ");
    522         }
    523     }
    524     while (!CheckName(name));
    525  
    526     /* 按姓名查找节点 */
    527     while (p != NULL)
    528     {
    529         if (strcmp(p->name, name) == 0)
    530         {
    531             ok = 0;
    532             OutputNodeInfo(p);
    533         }
    534         p = p->next;
    535     }
    536  
    537     if (ok)
    538     {
    539         printf("对不起,找不到这个姓名
    ");
    540     }
    541 }
    542  
    543 /* 计算总分和均分 */
    544 void Compute()
    545 {
    546     int i;
    547     Student *p = head->next;
    548  
    549     while (p != NULL)
    550     {
    551         int sum = 0;
    552  
    553         for (i = 0; i < N; i++)
    554         {
    555             sum += p->score[i];
    556         }
    557  
    558         p->sum = sum;
    559         p->ave = sum * 1.0 /N;
    560         p = p->next;
    561     }
    562 }
    563  
    564 /* 比较学号 */
    565 int CmpID(Student* a, Student* b, int k)
    566 {
    567     return strcmp(a->num, b->num);
    568 }
    569  
    570 /* 比较总分 */
    571 int CmpSum(Student* a, Student* b, int k)
    572 {
    573     return b->sum - a->sum;
    574 }
    575  
    576 /* 比较各科分数 */
    577 int CmpScore(Student* a, Student* b, int k)
    578 {
    579     return b->score[k] - a->score[k];
    580 }
    581  
    582 /* 选择最大元素 */
    583 Student* SearchMaxNode(int (*cmp)(Student* a, Student* b, int k), int k)
    584 {
    585     Student *p = head->next;
    586     Student *max = p;
    587  
    588     while (p != NULL)
    589     {
    590         if (cmp(p, max, k) < 0)
    591         {
    592             max = p;
    593         }
    594         p = p->next;
    595     }
    596  
    597     return max;
    598 }
    599  
    600 /* 排序 */
    601 Student* Sort(int (*cmp)(Student* a, Student* b, int k), int k)
    602 {
    603     Student *newhead = LEN;
    604     Student *p = newhead;
    605     Student *max;
    606  
    607     while (head->next != NULL)
    608     {
    609         max = SearchMaxNode(cmp, k);
    610         p->next = max;
    611         DeleteNode(max);
    612         p = p->next;
    613     }
    614  
    615     /* 表尾处理 */
    616     p->next = NULL;
    617     return newhead;
    618 }
    619  
    620 
    621 /* 将s插入链表尾部 */
    622 void InsertAfter(Student* s)
    623 
    624 {
    625     Student *p = head;
    626  
    627     while (p->next != NULL) p = p->next;
    628  
    629     s->next = NULL;
    630     p->next = s;
    631 }
    632  
    633 /* 保存到文件 */
    634 void SaveToFile()
    635 {    
    636     /* 处理尾部添加表尾情况 */
    637     if (SWITCH[12])
    638     {
    639         InsertAfter(tmp);
    640     }
    641  
    642     FILE *fp;
    643     int i;
    644     Student *p; 
    645     char file[20];
    646     fflush(stdin);
    647     printf("请输入要保存的文件名: ");
    648     gets(file);
    649  
    650     if ((fp = fopen(file, "wt")) == NULL)
    651     {
    652         printf("写文件错误.......!
    ");
    653         return;
    654     }
    655    for(p = head->next;p!=NULL;p=p->next)
    656      fprintf(fp,"%s %s 
    ",p->name,p->num);
    657        for(i=0;i<2;i++)
    658         {
    659          fprintf(fp,"%d
    ",p->score[i]);
    660          }  
    661     printf("文件保存成功!
    ");
    662     fclose(fp);
    663     SWITCH[6] = 1;
    664  
    665     /* 处理尾部添加情况 */
    666     if (SWITCH[12])
    667     {
    668         DeleteNode(tmp);
    669          SWITCH[12] = 0;
    670     }
    671 }
    672  
    673 /* 从文件中读入记录 */
    674 void LoadFile()
    675 {
    676     int i;
    677     FILE *fp;
    678     char file[20];
    679     fflush(stdin);
    680     printf("请输入文件名: ");
    681     gets(file);
    682  
    683     if ((fp = fopen(file, "rt")) == NULL)
    684     {
    685         printf("对不起,无法打开文件!
    ");
    686         return;
    687     }
    688  
    689     /* 文件未结束时读入数据 */
    690     while (!feof(fp))
    691     {
    692         Student *s = LEN;
    693         fscanf(fp, "%s", s->name);
    694         fscanf(fp, "%s", s->num);
    695  
    696         for (i = 0; i < N; i++)
    697         {
    698             fscanf(fp, "%d", &s->score[i]);
    699         }
    700  
    701         s->next = head->next;
    702         head->next = s;
    703     }
    704  
    705     printf("文件读取成功!
    ");
    706     fclose(fp);
    707 }
    708  
    709 /* 复制文件 */
    710 void CopyFile()
    711 {
    712     FILE *fp1, *fp2;
    713     char ch, file1[20], file2[20];
    714     fflush(stdin);
    715     /* 读入源文件 */
    716     printf("请输入源文件名: ");
    717     gets(file1);
    718  
    719     if ((fp1 = fopen(file1, "rb")) == NULL)
    720     {
    721         printf("对不起,无法打开文件!
    ");
    722         return;
    723     }
    724  
    725     /* 读入目标文件 */
    726     printf("请输入目标文件名: ");
    727     gets(file2);
    728  
    729     if ((strcmp(file1, file2) == 0) || ((fp2 = fopen(file2, "wb")) == NULL))
    730     {
    731         printf("对不起,无法创建文件!
    ");
    732         return;
    733     }
    734  
    735     /* 逐个字符拷贝 */
    736     while (!feof(fp1))
    737     {
    738         ch = fgetc(fp1);
    739  
    740         if (ch != EOF)
    741             fputc(ch, fp2);
    742     }
    743  
    744     fclose(fp1);
    745     fclose(fp2);
    746     printf("文件拷贝成功!
    ");
    747 }
    748  
    749 /* 尾部添加记录到文件中 */
    750 void InsertToFile()
    751 {
    752     tmp = LEN;
    753     InputNodeInfo(tmp);
    754     SWITCH[12] = 1;
    755 }
    756  
    757 /* 分类统计 */
    758 void Stat()
    759 {
    760     int i, j, n = 0;
    761     int sum[N] = {0};
    762     Student *p = head->next;
    763  
    764     if (p == NULL)
    765     {
    766         printf("暂无学生信息,无法统计
    ");
    767         return;
    768     }
    769  
    770     /* 统计各科总分 */
    771     while (p != NULL)
    772     {
    773         /* 记录学生总数 */
    774         n++;
    775  
    776         for (i = 0; i < N; i++)
    777         {
    778             sum[i] += p->score[i];
    779         }
    780  
    781         p = p->next;
    782     }
    783  
    784     /* 各科分别输出 */
    785     for (i = 0; i < N; i++)
    786     {
    787         printf("%s 总均分: %.2lf
    ", CLASSNAME[i], sum[i] * 1.0 / n);
    788         head = Sort(CmpScore, i);
    789         j = 0;
    790         p = head->next;
    791  
    792         while (p != NULL)
    793         {
    794             j++;
    795             printf("第%d名 %s %d
    ", j, p->name, p->score[i]);
    796             p = p->next;
    797         }
    798  
    799         printf("
    ");
    800     }
    801 }
    802  
    803 /* 释放链表 */
    804 void FreeList(Student* p)
    805 {
    806     if (p->next != NULL)
    807     {
    808         FreeList(p->next);
    809     }
    810     free(p);
    811 }
    812  
    813 /* 退出 */
    814 void Quit()
    815 {
    816     if (!SWITCH[6])
    817     {
    818         printf("请先保存文件!
    ");
    819         return;
    820     }
    821     if (head != NULL)
    822     {
    823         FreeList(head);
    824     }    
    825     exit(0);
    826 }
  • 相关阅读:
    xuexi
    太厉害了!腾讯T4大牛把《数据结构与算法》讲透了,带源码笔记
    python 死循环
    redis 锁
    Opencv4.1.0交叉编译----终端摄像头内算法嵌入,海思HISI、雄迈ARM编译链使用经验
    SpringCloud之FeignClient调用跨微服接口
    Elasticsearch父子级查询及祖孙辈parent/child关联查询
    服务器ip地址与域名解析及http转https
    RestTemplate请求第三方接口添加Headers token及设置请求体
    kanzi 一些基础参数变量
  • 原文地址:https://www.cnblogs.com/Zblogs/p/3345091.html
Copyright © 2020-2023  润新知