学生管理系统管理系统

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

 

  -----------------完成时间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...初始化成功\n");
 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("当前文件未保存\n");
110                         }
111                         break;
112                         /* 计算所有学生的总分和平均分 */
113                     case 8:
114                         Compute();
115                         SWITCH[8] = 1;
116                         printf("计算完毕\n");
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("请先计算总分!\n");
139                         }
140                         break;
141                         /* 尾部添加一个学生信息到文件中 */
142                     case 12:
143                         InsertToFile();
144                         SWITCH[6] = 0;
145                         printf("尾部添加完毕!\n");
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("请先计算总分!\n");
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("无效命令编号!\n");
171                         fflush(stdin);
172                 }
173                 system("pause");
174             }
175             else
176             {
177                 printf("你必须首先初始化!\n");
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("*********************************************************************\n");
194     printf("*********************************************************************\n");
195     printf("【01】 初始化........\n");
196     printf("【02】 输入学生信息\n");
197     printf("【03】 查找学号或姓名删除信息\n");
198     printf("【04】 输出全部学生信息\n");
199     printf("【05】 按姓名查找学生信息\n");
200     printf("【06】 保存到文件\n");
201     printf("【07】 从文件中读取学生信息\n");
202     printf("【08】 计算所有学生的总分和平均分\n");
203     printf("【09】 插入一个学生信息到链表中\n");
204   //  printf("【10】 复制文件\n");
205     printf("【11】 按总分排序并打印学生信息\n");
206     printf("【12】 尾部添加一个学生信息到文件中\n");
207     printf("【13】 按学号搜索..学生信息\n");
208     printf("【14】 分类汇总\n");
209     printf("【15】 退出\n");
210     printf("********************************************************************\n");
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("\n请输入学号: ");
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("\n");
345     printf("姓名: %s\n", p->name);
346     printf("学号: %s\n", p->num);
347        
348     for (i = 0; i < N; i++)
349     {
350         printf("%s 成绩: %d\n", CLASSNAME[i], p->score[i]);
351     }
352        
353     /* 计算过才输出 */
354     if (SWITCH[8]) printf("总分: %d\n", p->sum);
355     if (SWITCH[8]) printf("平均分: %.2lf\n", 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("对不起,找不到这个学号\n");
449         }
450         else
451         {
452             OutputNodeInfo(p);
453             printf("确认删除? (输入\"y\"确认,任意键取消): ");
454             if (strcmp(gets(sure), "y") == 0)
455             {
456                 DeleteNode(p);
457                 printf("删除成功\n");
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("对不起,找不到这个姓名\n");
470         }
471         else
472         {
473             OutputNodeInfo(p);
474             printf("确认删除? (输入\"y\"确认,任意键取消): ");
475             if (strcmp(gets(sure), "y") == 0)
476             {
477                 DeleteNode(p);
478                 printf("删除成功!\n");
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("暂无学生信息!\n");
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("对不起,找不到这个姓名\n");
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("写文件错误.......!\n");
648         return;
649     }
650    for(p = head->next;p!=NULL;p=p->next) //此段中大括号的使用位置错误直接导致程序出现严重的段错误(linux实验室)
651      { fprintf(fp,"%s %s\n",p->name,p->num );
652         for(i=0;i<=2;i++)
653          {
654           fprintf(fp,"%d\n",p->score[i]);
655           }
656      }
657        printf("文件保存成功!\n");
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("对不起,无法打开文件!\n");
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\n", &s->score[i]);
694         }
695        
696         s->next = head->next;
697         head->next = s;
698     }
699        
700     printf("文件读取成功!\n");
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("对不起,无法打开文件!\n");
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("对不起,无法创建文件!\n");
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("文件拷贝成功!\n");
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("暂无学生信息,无法统计\n");
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\n", 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\n", j, p->name, p->score[i]);
791             p = p->next;
792         }
793        
794         printf("\n");
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("请先保存文件!\n");
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...初始化成功\n");
 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("当前文件未保存\n");
110                         }
111                         break;
112                         /* 计算所有学生的总分和平均分 */
113                     case 8:
114                         Compute();
115                         SWITCH[8] = 1;
116                         printf("计算完毕\n");
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("请先计算总分!\n");
139                         }
140                         break;
141                         /* 尾部添加一个学生信息到文件中 */
142                     case 12:
143                         InsertToFile();
144                         SWITCH[6] = 0;
145                         printf("尾部添加完毕!\n");
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("请先计算总分!\n");
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("无效命令编号!\n");
171                         fflush(stdin);
172                 }
173                 system("pause");
174             }
175             else
176             {
177                 printf("你必须首先初始化!\n");
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("*********************************************************************\n");
194     printf("*********************************************************************\n");
195     printf("【01】 初始化........\n");
196     printf("【02】 输入学生信息\n");
197     printf("【03】 查找学号或姓名删除信息\n");
198     printf("【04】 输出全部学生信息\n");
199     printf("【05】 按姓名查找学生信息\n");
200     printf("【06】 保存到文件\n");
201     printf("【07】 从文件中读取学生信息\n");
202     printf("【08】 计算所有学生的总分和平均分\n");
203     printf("【09】 插入一个学生信息到链表中\n");
204   //  printf("【10】 复制文件\n");
205     printf("【11】 按总分排序并打印学生信息\n");
206     printf("【12】 尾部添加一个学生信息到文件中\n");
207     printf("【13】 按学号搜索..学生信息\n");
208     printf("【14】 分类汇总\n");
209     printf("【15】 退出\n");
210     printf("********************************************************************\n");
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("\n请输入学号: ");
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("\n");
345     printf("姓名: %s\n", p->name);
346     printf("学号: %s\n", p->num);
347        
348     for (i = 0; i < N; i++)
349     {
350         printf("%s 成绩: %d\n", CLASSNAME[i], p->score[i]);
351     }
352        
353     /* 计算过才输出 */
354     if (SWITCH[8]) printf("总分: %d\n", p->sum);
355     if (SWITCH[8]) printf("平均分: %.2lf\n", 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("对不起,找不到这个学号\n");
449         }
450         else
451         {
452             OutputNodeInfo(p);
453             printf("确认删除? (输入\"y\"确认,任意键取消): ");
454             if (strcmp(gets(sure), "y") == 0)
455             {
456                 DeleteNode(p);
457                 printf("删除成功\n");
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("对不起,找不到这个姓名\n");
470         }
471         else
472         {
473             OutputNodeInfo(p);
474             printf("确认删除? (输入\"y\"确认,任意键取消): ");
475             if (strcmp(gets(sure), "y") == 0)
476             {
477                 DeleteNode(p);
478                 printf("删除成功!\n");
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("暂无学生信息!\n");
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("对不起,找不到这个姓名\n");
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("写文件错误.......!\n");
648         return;
649     }
650    for(p = head->next;p!=NULL;p=p->next) //此段中大括号的使用位置错误直接导致程序出现严重的段错误(linux实验室)
651      { fprintf(fp,"%s %s\n",p->name,p->num );
652         for(i=0;i<=2;i++)
653          {
654           fprintf(fp,"%d\n",p->score[i]);
655           }
656      }
657        printf("文件保存成功!\n");
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("对不起,无法打开文件!\n");
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\n", &s->score[i]);
694         }
695        
696         s->next = head->next;
697         head->next = s;
698     }
699        
700     printf("文件读取成功!\n");
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("对不起,无法打开文件!\n");
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("对不起,无法创建文件!\n");
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("文件拷贝成功!\n");
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("暂无学生信息,无法统计\n");
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\n", 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\n", j, p->name, p->score[i]);
791             p = p->next;
792         }
793        
794         printf("\n");
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("请先保存文件!\n");
814         return;
815     }
816     if (head != NULL)
817     {
818         FreeList(head);
819     } 
820     exit(0);
821 }

 

posted @ 2015-06-19 18:36  阿司★*^_^*联波  阅读(659)  评论(0编辑  收藏  举报