• 学生管理系统管理系统


    本系统是大一课程设计中课程设计做出来的!

      -----------------完成时间2013 06 08

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

    ---恢复内容结束---

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