学生管理系统(C语言)

  1 #include 
  2 #include 
  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...初始化成功\n");
 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("当前文件未保存\n");
108                         }
109                         break;
110                         /* 计算所有学生的总分和平均分 */
111                     case 8:
112                         Compute();
113                         SWITCH[8] = 1;
114                         printf("计算完毕\n");
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("请先计算总分!\n");
137                         }
138                         break;
139                         /* 尾部添加一个学生信息到文件中 */
140                     case 12:
141                         InsertToFile();
142                         SWITCH[6] = 0;
143                         printf("尾部添加完毕!\n");
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("请先计算总分!\n");
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("无效命令!\n");
169                         fflush(stdin);
170                 }
171                 system("pause");
172             }
173             else
174             {
175                 printf("你必须首先初始化!\n");
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("*********************************************************************\n");
192     printf("*********************************************************************\n");
193     printf("【01】 初始化........\n");
194     printf("【02】 输入学生信息\n");
195     printf("【03】 查找学号或姓名删除信息\n");
196     printf("【04】 输出全部学生信息\n");
197     printf("【05】 按姓名查找学生信息\n");
198     printf("【06】 保存到文件\n");
199     printf("【07】 从文件中读取学生信息\n");
200     printf("【08】 计算所有学生的总分和平均分\n");
201     printf("【09】 插入一个学生信息到链表中\n");
202     printf("【10】 复制文件\n");
203     printf("【11】 按总分排序并打印学生信息\n");
204     printf("【12】 尾部添加一个学生信息到文件中\n");
205     printf("【13】 按学号搜索..学生信息\n");
206     printf("【14】 分类汇总\n");
207     printf("【15】 退出\n");
208     printf("********************************************************************\n");
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("\n请输入学号: ");
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("\n");
343     printf("姓名: %s\n", p->name);
344     printf("学号: %s\n", p->num);
345  
346     for (i = 0; i < N; i++)
347     {
348         printf("%s 成绩: %d\n", CLASSNAME[i], p->score[i]);
349     }
350  
351     /* 计算过才输出 */
352     if (SWITCH[8]) printf("总分: %d\n", p->sum);
353     if (SWITCH[8]) printf("平均分: %.2lf\n", 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("对不起,找不到这个学号\n");
450         }
451         else
452         {
453             OutputNodeInfo(p);
454             printf("确认删除? (输入\"y\"确认,任意键取消): ");
455             if (strcmp(gets(sure), "y") == 0)
456             {
457                 DeleteNode(p);
458                 printf("删除成功\n");
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("对不起,找不到这个姓名\n");
471         }
472         else
473         {
474             OutputNodeInfo(p);
475             printf("确认删除? (输入\"y\"确认,任意键取消): ");
476             if (strcmp(gets(sure), "y") == 0)
477             {
478                 DeleteNode(p);
479                 printf("删除成功!\n");
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("暂无学生信息!\n");
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("对不起,找不到这个姓名\n");
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("写文件错误.......!\n");
653         return;
654     }
655    for(p = head->next;p!=NULL;p=p->next)
656      fprintf(fp,"%s %s \n",p->name,p->num);
657        for(i=0;i<2;i++)
658         {
659          fprintf(fp,"%d\n",p->score[i]);
660          }  
661     printf("文件保存成功!\n");
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("对不起,无法打开文件!\n");
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("文件读取成功!\n");
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("对不起,无法打开文件!\n");
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("对不起,无法创建文件!\n");
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("文件拷贝成功!\n");
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("暂无学生信息,无法统计\n");
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\n", 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\n", j, p->name, p->score[i]);
796             p = p->next;
797         }
798  
799         printf("\n");
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("请先保存文件!\n");
819         return;
820     }
821     if (head != NULL)
822     {
823         FreeList(head);
824     }    
825     exit(0);
826 }

 

转载于:https://www.cnblogs.com/Zblogs/p/3345091.html

你可能感兴趣的:(c/c++,数据结构与算法)