C语言实验编程:学生成绩管理系统。

一、实验名称
学生成绩管理系统。
二、实验任务
(一)程序运行时,首先显示主菜单如下:
1新建数据
2添加数据
3删除数据
4排序
5查询
6退出
屏幕提示:请输入序号选择相应操作。
要求当用户输入任意序号后,程序都能进行相应操作。
(二)在主菜单中选择序号4,弹出子菜单选择排序方式,子菜单如下:
数学成绩排序
程序设计成绩排序
总分排序。
返回主菜单
请按序号选择相应操作。
选择子菜单的序号后,程序能正确运行并在屏幕上显示按要求排序后的相关信息。
(三)在主菜单中选择序号5,弹出子菜单选择查询方式,子菜单如下:
学号查询
姓名查询
数学成绩查询
程序设计成绩查询
总分查询
返回主菜单
请按序号选择相应操作。
在子菜单中选择序号后,程序按以下方式工作:
1)学号查询:输入学号后,若该学号存在则显示与其相关的所有信息,否则显示找不到的提示信息;(提示:查询到满足条件的结果后,查询即可结束)
2)姓名查询:输入姓名后,若该姓名存在则显示与其相关的所有信息,否则显示找不到的提示信息;(提示:使用字符串比较函数进行比较)
3)按科目查询:输入指定分数,程序运行后显示该科目中考试成绩大于等于指定分数的同学的学号、姓名以及该科成绩并统计满足条件的人数;
4)总分查询:输入指定分数,程序运行后显示总分成绩大于等于指定分数的同学的学号、姓名以及各科成绩并统计满足条件的人数。

// 学生管理系统.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "string.h"
#include "conio.h"
#include "windows.h"
#include "stdlib.h"

#define LIST_TITLE "学号 姓名 性别 语文 数学 英语\n"
#define LIST_TITLE_1 "学号 姓名 性别 语文 数学 英语 均分\n"
#define FILE_DATABASE "C:\\student_database.dat"
#define FILE_EXPORT "C:\\student_export.txt"
//颜色
enum
{
 BLACK,
 BLUE,
 GREEN,
 CYAN,
 RED,
 MAGENTA,
 BROWN,
 LIGHTGRAY,
 DARKGRAY,
 LIGHTBLUE,
 LIGHTGREEN,
 LIGHTCYAN,
 LIGHTRED,
 LIGHTMAGENTA,
 YELLOW,
 WHITE
};
//功能索引
enum
{
 Func_Add = 1,//添加学生信息
 Func_Delete,//删除
 Func_Modify,//修改
 Func_Search,//搜索
 Func_Sort,//排序
 Func_Save,//保存
 Func_AutoSave,//自动保存
 Func_Vote,//投票系统
 Func_Export,//导出学生信息
 Func_ExitSystem//退出系统
};
struct Student
{
 int num;//学号
 char name[20];//姓名
 char sex[8];//性别
 float score[3];//三门课程成绩
 float averge;//平均分
 int count;//投票计数
 Student* pNext;

};
Student* G_pStuHead;//链表头
bool G_autoStore = false;//自动保存

/************************************************************************/
/*设置字体颜色*/
/************************************************************************/
void setFontColor(int ForgC)
{
 WORD wColor;
 HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
 CONSOLE_SCREEN_BUFFER_INFO csbi;
 
 if(GetConsoleScreenBufferInfo(hOutput, &csbi))
 {
  //设置字体颜色
  wColor = (csbi.wAttributes & 0xF0) + (ForgC & 0x0F);
  SetConsoleTextAttribute(hOutput, wColor);
 }
}
/************************************************************************/
/*光标跳转到指定位置*/
/************************************************************************/
void gotoxy(int x, int y)
{
    // 更新光标位置 
    COORD pos;
 
    HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    pos.X = x;
    pos.Y = y;
    SetConsoleCursorPosition(hOutput, pos);
 // 隐藏光标 
//     CONSOLE_CURSOR_INFO cursor;
//     cursor.bVisible = FALSE;
//     cursor.dwSize = 1; //值介于1 ~ 100 之间 单元格底部为下划线 ~ 完全填充单元格
//     SetConsoleCursorInfo(hOutput, &cursor);
 
}
/************************************************************************/
/*主菜单中指定位置打印是否自动保存*/
/************************************************************************/
void printAutoStoreInfo()
{
 setFontColor(LIGHTGREEN);
 gotoxy(13, 10);
 printf("%s\n", G_autoStore ? "是" : "否");
 setFontColor(WHITE);
}
/************************************************************************/
/*显示最上面的系统标题*/
/************************************************************************/
void showSystemTitle()
{
 setFontColor(LIGHTGREEN);
 printf("--------------------------------------------------------\n");
 printf("\t\t欢迎进入学生管理系统\n");
 printf("--------------------------------------------------------\n");
 setFontColor(WHITE);
}
/************************************************************************/
/*初始化屏幕*/
/************************************************************************/
void initScreen()
{
 system("CLS");
 showSystemTitle();
 printf("请输入数字序列号,选择您要执行的操作:\n");
 printf("1、添加学生信息\n");
 printf("2、删除学生信息\n");
 printf("3、修改学生信息\n");
 printf("4、查询学生信息\n");
 printf("5、排序\n");
 printf("6、保存(如打开自动保存,则无需手动执行)\n");
 printf("7、自动保存:");
 printAutoStoreInfo();
 printf("8、投票系统\n");
 printf("9、导出学生信息\n");
 setFontColor(LIGHTRED);
 printf("10、退出学生管理系统\n");
 setFontColor(WHITE);

}
/************************************************************************/
/*从指定位置开始清除指定长度元素*/
/************************************************************************/
void gotodelete(int x, int y, int length)
{
 int i;
    
 for (i = 0; i < length; i++)
 {
  gotoxy(x + i, y);
  printf(" ");
 }
}
/************************************************************************/
/*清除指定位置元素*/
/************************************************************************/
void gotodelete(int x, int y)
{
 gotodelete(x, y, 1);
}
/************************************************************************/
/*投票系统 */
/************************************************************************/
void voteSystem()
{
 bool hasFound;
 char name[20];
 int count, i, j;
 Student* pStu, *pTmp;
 Student** pStuArr;

 //初始化票数清零
 pStu = G_pStuHead->pNext;
 while(pStu != NULL)
 {
  pStu->count = 0;
  pStu = pStu->pNext;
 }

 count = 0;
 pStuArr = (Student**)malloc(4 * 100);//用于存放已经获得票数的同学指针
 gotoxy(0, 6);
 printf("投票结果如下:\n");
 gotoxy(0, 3);
 printf("请在下方输入你想投给的人的姓名(输入-1返回主菜单):\n");
 
 while (1)
 {
  gotodelete(0, 4, 20);//清空输入行
  gotoxy(0, 4);
  scanf("%s", name);
  
  if(strcmp(name, "-1") == 0)
  {
   break;
  }
  hasFound = false;
  pStu = G_pStuHead->pNext;
  //在系统中查找对应的人名
  while(pStu != NULL)
  {
   if(strcmp(pStu->name, name) == 0)
   {
    hasFound = true;
    break;
   }
   pStu = pStu->pNext;
  }
  if(! hasFound)
  {
   printf("查无此人!!!");
   Sleep(1000);
   gotodelete(0, 5, 20);
   continue;
  }
  //找到之后,这个人所对应的票数+1
  pStu->count++;
  for (i = 0; i < count; i++)
  {
   if(pStuArr[i] == pStu)
   {
    break;
   }
  }
  if(i == count)//说明未找到,则添加进候选人数组
  {
   pStuArr[count++] = pStu;
   if(count % 100 == 0)
   {
    pStuArr = (Student**)realloc(pStuArr, count + 100);
   }
  }
  //冒泡排序,票数
  for (i = 0; i < count - 1; i++)
  {
   for (j = i + 1; j < count; j++)
   {
    if(pStuArr[i]->count < pStuArr[j]->count)
    {
     pTmp = pStuArr[i];
     pStuArr[i] = pStuArr[j];
     pStuArr[j] = pTmp;
    }
   }
  }
  gotoxy(0, 7);//跳转到打印票数的那行
  //打印票数
  for (i = 0; i < count; i++)
  {
   if(i == 0)
   {
    setFontColor(LIGHTGREEN);
   }
   else
   {
    setFontColor(WHITE);
   }
   printf("%d %s\t%d\n", pStuArr[i]->num, pStuArr[i]->name, pStuArr[i]->count);
  }

 }
 free(pStuArr);
 
}
/************************************************************************/
/*导出学生信息(明文) */
/************************************************************************/
bool exportStudentInfo()
{
 Student* pStu;
 FILE* fp;

 pStu = G_pStuHead->pNext;

 if((fp = fopen(FILE_EXPORT, "w")) == NULL)
 {
  return false;
 }
 while (pStu != NULL)
 {
  fprintf(fp, "%d %s  %s %.2f %.2f %.2f %.2f\n", pStu->num, pStu->name, pStu->sex, 
       pStu->score[0], pStu->score[1], pStu->score[2], pStu->averge);
  pStu = pStu->pNext;
 }
 fclose(fp);
 return true;
}
/************************************************************************/
/*保存学生信息 (以数据库形式保存)*/
/************************************************************************/
bool saveStudentInfo()
{
 FILE *fp;
 Student *pStu;

 pStu = G_pStuHead;

 if((fp = fopen(FILE_DATABASE, "wb")) == NULL)
 {
  return false;
 }
 fwrite(&G_autoStore, sizeof(G_autoStore), 1, fp);
 while (pStu != NULL)
 {
  fwrite(pStu, sizeof(Student), 1, fp);
  pStu = pStu->pNext;
 }
 fclose(fp);
 return true;
}
/************************************************************************/
/*读取学生信息(读取数据库形式的文档) */
/************************************************************************/
bool loadStudentInfo()
{
 FILE *fp;
 int count;
 Student stu, *pStu, *pStuNew;

 count = 0;
 pStu = G_pStuHead;

 if((fp = fopen(FILE_DATABASE, "rb")) == NULL)
 {
  return false;
 }
 fread(&G_autoStore, sizeof(G_autoStore), 1, fp);//读取是否自动保存
 while(1)
 {
  fread(&stu, sizeof(Student), 1, fp);//读取文档中每个同学的数据
  if(feof(fp))//到文档尾则跳出
  {
   break;
  }
  if(count++ > 0)//这里 > 0 是因为保存的时候会把链表头保存进去,而链表头是没有有效数据的,所以要排除掉
  {
   pStuNew = (Student*)malloc(sizeof(Student));
   MoveMemory(pStuNew, &stu, sizeof(Student) - 4);//将结构体除指针外的所有数据拷贝进内存
   pStuNew->pNext = NULL;
   pStu->pNext = pStuNew;
   pStu = pStuNew;
  }
  if(stu.pNext == NULL)
  {
   break;
  }
 }
 fclose(fp);
 return true;
}
/************************************************************************/
/*学生信息排序 */
/************************************************************************/
bool sortStudentInfo()
{
 int order1, order2;
 bool swapData;
 char yesOrNo;
 Student* pStu1, *pStu2, tmpStu;

 pStu1 = G_pStuHead->pNext;
 if(pStu1 == NULL)
 {
  printf("系统中无学生信息!\n");
  system("pause");
  return false;
 }
 printf("输入以下序号执行相应功能(输入其他序号返回主菜单):\n");
 printf("1、根据学号进行排序\n");
 printf("2、根据姓名排序\n");
 printf("3、根据语文成绩排序\n");
 printf("4、根据数学成绩排序\n");
 printf("5、根据英语成绩排序\n");
 printf("6、根据平均分成绩排序\n");

 scanf("%d", &order1);
 if(order1 >= 1 && order1 <= 6)
 {
  printf("请选择正序OR倒序排列?(输入其他序号返回主菜单)\n");
  printf("1、正序排列\n");
  printf("2、倒序排列\n");
  scanf("%d", &order2);
  if(order2 >= 1 && order2 <= 2)
  {
   //冒泡排序
   for ( ; pStu1->pNext != NULL; pStu1 = pStu1->pNext)
   {
    for (pStu2 = pStu1->pNext; pStu2 != NULL; pStu2 = pStu2->pNext)
    {
     swapData = false;//是否交换数据
     switch(order1)
     {
     case 1://根据学号排序
      {
       if(order2 == 1 ? (pStu1->num > pStu2->num) : (pStu1->num < pStu2->num))//三目运算符, 判断正序还是倒序
       {
        swapData = true;
       }
       break;
      }
     case 2://根据姓名排序
      {
       if(order2 == 1 ? (strcmp(pStu1->name, pStu2->name) > 0) : (strcmp(pStu1->name, pStu2->name) < 0))
       {
        swapData = true;
       }
       break;
      }
     case 3://根据语文排序
     case 4://根据数学排序
     case 5://根据英语排序
      {
       if(order2 == 1 ? (pStu1->score[order1 - 3] > pStu2->score[order1 - 3]) : (pStu1->score[order1 - 3] < pStu2->score[order1 - 3]))
       {
        swapData = true;
       }
       break;
      }
     case 6://根据均分排序
      {
       if(order2 == 1 ? (pStu1->averge > pStu2->averge) : (pStu1->averge < pStu2->averge))
       {
        swapData = true;
       }
       break;
      }
     }

     if(swapData)
     {
      //交换内存数据,只需要将除pNext指针外的结构体数据拷贝交换即可
      MoveMemory(&tmpStu, pStu1, sizeof(Student) - 4);
      MoveMemory(pStu1, pStu2, sizeof(Student) - 4);
      MoveMemory(pStu2, &tmpStu, sizeof(Student) - 4);
     }
    }
   }
   printf("排序完成,是否显示?Y/N\n");
   getchar();//过滤掉输入时的换行符
   scanf("%c", &yesOrNo);
   if(yesOrNo == 'Y' || yesOrNo == 'y')
   {
    pStu1 = G_pStuHead->pNext;
    setFontColor(LIGHTGREEN);
    printf(LIST_TITLE_1);//显示列表标题头
    setFontColor(WHITE);
    //打印排序后的各个学生信息
    while(pStu1 != NULL)
    {
     printf("%d %s  %s %.2f %.2f %.2f %.2f\n", pStu1->num, pStu1->name, pStu1->sex, 
       pStu1->score[0], pStu1->score[1], pStu1->score[2], pStu1->averge);
     pStu1 = pStu1->pNext;
    }
    system("pause");
   }
   return true;

  }
 }
 return false;
}
/************************************************************************/
/*查询学生信息 */
/************************************************************************/
void searchStudentInfo()
{
 bool hasFound;
 int order, stuID, count, i, min, max;
 float score;
 char name[20];
 Student* pStu;
 Student** pStuArr;

 pStuArr = NULL;
 
 while (1)
 {
  system("CLS");
  showSystemTitle();

  if(pStuArr != NULL)//如果再次查询,这里需要判断,将上一轮查询的学生信息指针数组清空
  {
   free(pStuArr);
  }
  count = 0;
  stuID = 0;
  hasFound = false;
  pStu = G_pStuHead->pNext;
  pStuArr = (Student**)malloc(4 * 100);//初始化查询到后存放的学生信息指针数组

  printf("输入以下序号执行相应功能(输入其他序号返回主菜单):\n");
  printf("1、输入学号查询信息\n");
  printf("2、输入姓名查询信息\n");
  printf("3、输入语文成绩范围查询信息\n");
  printf("4、输入数学成绩范围查询信息\n");
  printf("5、输入英语成绩范围查询信息\n");
  printf("6、输入平均分范围查询信息\n");
  printf("7、列出所有学生信息\n");

  scanf("%d", &order);
  switch(order)
  {
  case 1://根据学号查询
   {
    printf("请输入要查询的学生学号:");
    scanf("%d", &stuID);
    while (pStu != NULL)
    {
     if(pStu->num == stuID)
     {
      hasFound = true;
      break;
     }
     pStu = pStu->pNext;
    }
    if(hasFound)//
    {
     setFontColor(LIGHTGREEN);
     printf(LIST_TITLE_1);
     setFontColor(WHITE);
     printf("%d %s  %s %.2f %.2f %.2f %.2f\n", pStu->num, pStu->name, pStu->sex, 
       pStu->score[0], pStu->score[1], pStu->score[2], pStu->averge);
    }
    
    break;
   }
  case 2://根据姓名查询
   {
    printf("请输入要查询的学生姓名:");
    scanf("%s", name);
    while (pStu != NULL)
    {
     if(strcmp(pStu->name, name) == 0)
     {
      hasFound = true;
      pStuArr[count++] = pStu;
      if(count % 100 == 0)
      {
       pStuArr = (Student**)realloc(pStuArr, count + 100);
      }
     }
     pStu = pStu->pNext;
    }
    if(hasFound)
    {
     setFontColor(LIGHTGREEN);
     printf(LIST_TITLE_1);
     setFontColor(WHITE);
     for (i = 0; i < count; i++)
     {
      printf("%d %s  %s %.2f %.2f %.2f %.2f\n", pStuArr[i]->num, pStuArr[i]->name, pStuArr[i]->sex, 
        pStuArr[i]->score[0], pStuArr[i]->score[1], pStuArr[i]->score[2], pStuArr[i]->averge);
     }

    }
    break;
   }
  case 3://根据语文成绩范围查询
  case 4://根据数学成绩范围查询
  case 5://根据英语成绩范围查询
  case 6://根据平均分范围查询
   {
    char *subjectStrArr[4] = {"语文", "数学", "英语", "平均"};
    printf("请输入要查询的%s成绩范围:", subjectStrArr[order - 3]);
    scanf("%d %d", &min, &max);
    while (pStu != NULL)
    {
     if(order < 6)// 3 ~ 5
     {
      score = pStu->score[order - 3];
     }
     else  //order = 6
     {
      score = pStu->averge;
     }
     if(score >= min && score <= max)
     {
      //找到符合条件的学生信息,则加入到指针数组中去
      hasFound = true;
      pStuArr[count++] = pStu;
      if(count % 100 == 0)
      {
       pStuArr = (Student**)realloc(pStuArr, count + 100);
      }
     }
     pStu = pStu->pNext;
    }
    if(hasFound)
    {
     setFontColor(LIGHTGREEN);
     printf(LIST_TITLE_1);
     setFontColor(WHITE);
     //打印指针数组中的学生信息
     for (i = 0; i < count; i++)
     {
      printf("%d %s  %s %.2f %.2f %.2f %.2f\n", pStuArr[i]->num, pStuArr[i]->name, pStuArr[i]->sex, 
       pStuArr[i]->score[0], pStuArr[i]->score[1], pStuArr[i]->score[2], pStuArr[i]->averge);
     }
     
    }
    break;
   }
  case 7://列出所有学生信息
   {
    hasFound = true;
    setFontColor(LIGHTGREEN);
    printf(LIST_TITLE_1);
    setFontColor(WHITE);
    while(pStu != NULL)
    {
     printf("%d %s  %s %.2f %.2f %.2f %.2f\n", pStu->num, pStu->name, pStu->sex, 
       pStu->score[0], pStu->score[1], pStu->score[2], pStu->averge);
     pStu = pStu->pNext;
    }
    break;
   }
  default:
   {
    goto lab_search;
   }
  }
  if(! hasFound)
  {
   printf("未能找到相应的学生信息!\n");
  }
  system("pause");
 }
lab_search:
 free(pStuArr);
}
/************************************************************************/
/*删除学生信息 */
/************************************************************************/
bool deleteStudentInfo()
{
 char yesOrNo;
 int stuID;
 bool hasFound;
 Student* pStu, *pStu1;

 hasFound = false;
 pStu = G_pStuHead->pNext;
 pStu1 = G_pStuHead;

 printf("请输入欲删除的学生学号:");
 scanf("%d", &stuID);
 while (pStu != NULL)
 {
  if(pStu->num == stuID)
  {
   hasFound = true;
   break;
  }
  pStu1 = pStu;
  pStu = pStu->pNext;
 }
 if(hasFound)
 {
  printf("找到此学生的信息如下:\n");
  setFontColor(LIGHTGREEN);
  printf(LIST_TITLE_1);
  setFontColor(WHITE);
  printf("%d %s  %s %.2f %.2f %.2f %.2f\n", pStu->num, pStu->name, pStu->sex, 
    pStu->score[0], pStu->score[1], pStu->score[2], pStu->averge);
  printf("是否删除?Y/N");
  getchar();//过滤掉输入时的换行符
  scanf("%c", &yesOrNo);
  if(yesOrNo == 'y' || yesOrNo == 'Y')
  {
   pStu1->pNext = pStu->pNext;
   free(pStu);
   printf("已删除\n");
  }
  else
  {
   hasFound = false;
  }
 }
 else
 {
  printf("未找到对应学生的信息\n");
 }
 system("pause");
 return hasFound;
}
/************************************************************************/
/*修改学生信息 */
/************************************************************************/
bool modifyStudentInfo()
{
 int order, count, i;
 int stuID;
 char name[20];
 char yesOrNo;
 bool hasModify;
 Student* pStu;
 Student** pStuArr;

 hasModify = false;
 count = 0;
 pStu = G_pStuHead->pNext;
 pStuArr = (Student**)malloc(4 * 100);//用于存放查找到的学生信息指针,这里定义指针数组是防止查询姓名出现重名

 printf("请输入以下序号,选择对应功能(1或2,否则返回上级菜单)\n");
 printf("1、输入学号查找学生\n");
 printf("2、输入姓名查找学生\n");
 scanf("%d", &order);

 if(order == 1)
 {
  printf("请输入要修改的学生学号:\n");
  scanf("%d", &stuID);
  while(pStu != NULL)
  {
   if(pStu->num == stuID)
   {
    pStuArr[count++] = pStu;
    break;
   }
   pStu = pStu->pNext;
  }
 }
 else if(order == 2)
 {
  printf("请输入要修改的学生姓名:\n");
  scanf("%s", name);
  while(pStu != NULL)
  {
   if(strcmp(pStu->name, name) == 0)
   {
    pStuArr[count++] = pStu;
    if(count % 100 == 0)//如果数组存放满了,则再次申请内存
    {
     pStuArr = (Student**)realloc(pStuArr, count + 100);
    }
   }
   pStu = pStu->pNext;
  }
 }
 else
 {
  return false;
 }
 if(count == 0)
 {
  printf("未能找到任何信息,是否继续修改?Y/N");
  getchar();//过滤掉输入时的换行符
  scanf("%c", &yesOrNo);
  if(yesOrNo == 'y' || yesOrNo == 'Y')
  {
   system("CLS");
   showSystemTitle();
   return modifyStudentInfo();
  }
 }
 else
 {
  printf("为您查找到%d个学生信息:\n   ", count);
  setFontColor(LIGHTGREEN);
  printf(LIST_TITLE);
  setFontColor(WHITE);
  for (i = 0; i < count; i++)
  {
   printf("%d、%d %s  %s %.2f %.2f %.2f\n", i + 1, pStuArr[i]->num, pStuArr[i]->name, pStuArr[i]->sex, 
    pStuArr[i]->score[0], pStuArr[i]->score[1], pStuArr[i]->score[2]);
  }

  printf("请输入您要修改的信息序号(1~%d),其他数字返回主菜单\n", count);
  scanf("%d", &order);
  if(order >= 1 && order <= count)
  {
   printf("请依次输入\n");
   setFontColor(LIGHTGREEN);
   printf(LIST_TITLE);
   setFontColor(WHITE);
   pStu = pStuArr[order - 1];
   scanf("%d %s %s %f %f %f", &pStu->num, pStu->name, pStu->sex, &pStu->score[0], &pStu->score[1], &pStu->score[2]);
   pStu->averge = (pStu->score[0] + pStu->score[1] + pStu->score[2]) / 3;
   hasModify = true;
  }
 }
 free(pStuArr);
 return hasModify;
}
/************************************************************************/
/*检测学号是否存在*/
/************************************************************************/
bool checkStuIDExist(int stuID)
{
 Student* pStu;

 pStu = G_pStuHead->pNext;

 while(pStu != NULL)
 {
  if(pStu->num == stuID)
  {
   return true;
  }
  pStu = pStu->pNext;
 }
 return false;
}
/************************************************************************/
/*添加学生信息 */
/************************************************************************/
bool addStudentInfo()
{
 printf("输入-1回车,返回上级菜单\n");
 setFontColor(LIGHTGREEN);
 printf(LIST_TITLE);
 setFontColor(WHITE);

 char c;
 bool hasAdd = false;
 Student* pStu = G_pStuHead;
 Student* pStuNew;

 while (pStu->pNext != NULL)
 {
  pStu = pStu->pNext;
 }

 while(1)
 {
  pStuNew = (Student*)malloc(sizeof(Student));
  scanf("%d", &pStuNew->num);
  if(pStuNew->num == -1)//输入-1返回主菜单
  {
   while ((c = getchar()) != EOF && c != '\n');//不停地使用getchar()获取缓冲中字符,直到获取的c是“\n”或文件结尾符EOF为止
   free(pStuNew);
   return hasAdd;
  }
  else if(checkStuIDExist(pStuNew->num))
  {
   while ((c = getchar()) != EOF && c != '\n');//不停地使用getchar()获取缓冲中字符,直到获取的c是“\n”或文件结尾符EOF为止
   printf("该学号已存在,请重新输入!\n");
   free(pStuNew);
   continue;
  }
  hasAdd = true;
  scanf("%s %s %f %f %f", pStuNew->name, pStuNew->sex, &pStuNew->score[0], 
   &pStuNew->score[1], &pStuNew->score[2]);
  pStuNew->averge = (pStuNew->score[0] + pStuNew->score[1] + pStuNew->score[2]) / 3;
  pStuNew->pNext = NULL;
  pStu->pNext = pStuNew;
  pStu = pStuNew;
 }

 return hasAdd;
}
/************************************************************************/
/*根据指令序号执行对应功能  */
/************************************************************************/
bool orderToExecute(int order)
{
 bool succ;

 succ = false;
 if(order != Func_Save && order != Func_AutoSave && order!= Func_Export)
 {
  system("CLS");
  showSystemTitle();
 }

 switch (order)
 {
 case Func_Add://添加
  {
   succ = addStudentInfo();
   break;
  }
 case Func_Delete://删除
  {
   succ = deleteStudentInfo();
   break;
  }
 case Func_Modify://修改
  {
   succ = modifyStudentInfo();
   break;
  }
 case Func_Search://搜索
  {
   searchStudentInfo();
   break;
  }
 case Func_Sort://排序
  {
   succ = sortStudentInfo();
   break;
  }
 case Func_Save://保存
  {
   succ = saveStudentInfo();
   if(succ)
   {
    gotoxy(42, Func_Save + 3);
    setFontColor(LIGHTGREEN);
    printf("保存成功!");
    setFontColor(WHITE);
    gotodelete(0, Func_ExitSystem + 4, 2);
    gotoxy(0, Func_ExitSystem + 4);
   }
   return false;
  }
 case Func_AutoSave://设置自动保存
  {
   G_autoStore = ! G_autoStore;
   printAutoStoreInfo();
   orderToExecute(Func_Save);//保存配置
   break;
  }
 case Func_Vote://投票系统
  {
   voteSystem();
   break;
  }
 case Func_Export://导出所有学生信息(明文)
  {
   succ = exportStudentInfo();
   gotoxy(17, Func_Export + 3);
   setFontColor(LIGHTGREEN);
   if(succ)
   {
    printf("导出成功!");
   }
   else
   {
    printf("导出失败!");
   }
   setFontColor(WHITE);
   gotodelete(0, Func_ExitSystem + 4, 2);
   gotoxy(0, Func_ExitSystem + 4);
   return false;
  }
 default:
  {
   
   break;
  }
 }
 return succ;
}

int main(int argc, char* argv[])
{
 int order;
 bool succ;

 system("title 学生管理系统 by 机智蛋");
 order = 0;
 succ = false;
 G_pStuHead = (Student*)malloc(sizeof(Student));
 G_pStuHead->pNext = NULL;

 loadStudentInfo();

 while(1)
 {
  if(order != Func_Save && order != Func_AutoSave && order != Func_Export)//当输入这几个指令时不需要初始化屏幕
  {
   initScreen();
  }
  if(succ && order != Func_Save && G_autoStore)//执行自动保存
  {
   orderToExecute(Func_Save);
  }
  succ = false;

  do 
  {
   scanf("%d", &order);
   if(order >= Func_Add && order <= Func_ExitSystem)
   {
    break;
   }
   else
   {
    printf("指令错误,请重新输入\n");
   }
  } while (1);
  
  if(order == Func_ExitSystem)//退出
  {
   printf("欢迎下次继续使用,拜拜~~\n");
   return 0;
  }

  succ = orderToExecute(order);//执行功能

  
 }
 
 return 0;
}

【效果】

img


#ifndef __SCORE_H__
#define __SCORE_H__
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
// 班级学生的最大的个数
#define NUM 100
 
// 学生成绩管理系统的功能
#define INSERT 0//插入
#define DELECT 1//删除
#define UPDATE 2//修改
#define SELECT 3//查询
#define PRINT 4//遍历
#define SORT 5//排序
#define QUIT 6//退出
 
 
//声明一个学生成绩组成的结构体类型
typedef struct student_score
{
    int Maths;
    int Chinese;
    int English;
    int Total_score;
}score_t;
 
// 声明一个学生的结构体类型
typedef struct Student /*不省略结构体名*/
{
    char name[20];
    int age;
    char sex;
    score_t score;
} Student_t;
// 声明一个班级的结构体类型
typedef struct /*省略结构体名*/
{
    Student_t stu_arr[NUM];
    int count; // 记录学生的个数
} Class_t;
 
int insert_stu(Class_t *cls);//录入
 
int delete_stu(Class_t *cls);//删除
 
int update_stu(Class_t *cls);//修改
 
int select_stu(Class_t *cls);//查询
 
void print_all_stu(Class_t *cls);//遍历
 
void sort_stu(Class_t *cls);//排序
 
#endif // __SCORE_H__

参考

#include<stdio.h>
#include<windows.h>
#define Max 25
#define obj_num 5
struct Stu
{
    char Name[25];     //姓名
    int Number;        //学号
    int Language_score;//语文成绩
    int Math_score;    //数学成绩
    int English_score; //英语成绩
    int PE_score;      //体育成绩
    int C_score;       //C语言成绩
    int Sum_score;     //总成绩
};
void input(struct Stu Class[],int j)
{
    printf("输入第%d位同学姓名:",j+1);
    scanf("%s",Class[j].Name);
    getchar();
    printf("输入第%d位同学学号:",j+1);
    scanf("%d",&Class[j].Number);
    printf("输入第%d位同学语文成绩:",j+1);
    scanf("%d",&Class[j].Language_score);
    printf("输入第%d位同学数学成绩:",j+1);
    scanf("%d",&Class[j].Math_score);
    printf("输入第%d位同学英语成绩:",j+1);
    scanf("%d",&Class[j].English_score);
    printf("输入第%d位同学体育成绩:",j+1);
    scanf("%d",&Class[j].PE_score);
    printf("输入第%d位同学C语言成绩:",j+1);
    scanf("%d",&Class[j].C_score);
    Class[j].Sum_score=Class[j].Language_score+Class[j].Math_score+Class[j].English_score+Class[j].PE_score+Class[j].C_score;
}
void output(struct Stu Class[],int n)
{
    printf("---------------------------------------------\n");
    printf("姓名  学号  语文  数学  英语  体育  C语言  总分");
    printf("\n");
    int j;
    for(j=0; j<n; j++)
    {
        printf("%5s",Class[j].Name);
        printf("%5d",Class[j].Number);
        printf("%6d",Class[j].Language_score);
        printf("%6d",Class[j].Math_score);
        printf("%6d",Class[j].English_score);
        printf("%6d",Class[j].PE_score);
        printf("%6d",Class[j].C_score);
        printf("%7d",Class[j].Sum_score);
        printf("\n");
    }
    printf("---------------------------------------------\n");
}
void outputOne(struct Stu Class[],int j)
{
    printf("姓名  学号  语文  数学  英语  体育  C语言  总分");
    printf("\n");
    printf("%5s",Class[j].Name);
    printf("%5d",Class[j].Number);
    printf("%6d",Class[j].Language_score);
    printf("%6d",Class[j].Math_score);
    printf("%6d",Class[j].English_score);
    printf("%6d",Class[j].PE_score);
    printf("%6d",Class[j].C_score);
    printf("%7d",Class[j].Sum_score);
    printf("\n");
}
void Sort(struct Stu Class[],int n)
{
    int j,k;
    struct Stu t;
    for(j=0; j<n-1; j++)
    {
        for(k=0; k<n-j-1; k++)
        {
            if(Class[k].Sum_score<Class[k+1].Sum_score)
            {
                t=Class[k];
                Class[k]=Class[k+1];
                Class[k+1]=t;
            }
        }
    }
}
int search(int number,int n,struct Stu Class[])
{
    int i,p=0;
    for(i=0; i<n; i++)
    {
        if(Class[i].Number==number)
        {
            p=i;
            return p;
        }
    }
    return -1;
}
void modify(int number,int n,struct Stu Class[])
{
    int index=search(number,n,Class);
    if(index==-1)
    {
        printf("找不到该学号\n");
    }
    else
    {
        printf("学号%d的学生是第%d位\n",number,index+1);
        input(Class,index);
        printf("修改成功\n");
        output(Class,n);
    }
}
void del(int number,int n,struct Stu Class[])
{
    int index=search(number,n,Class);
    if(index==-1)
    {
        printf("找不到该学号\n");
    }
    else
    {
        printf("学号%d的学生是第%d位\n",number,index);
        int i;
        for(i=index; i<n-1; i++)
        {
            Class[i]= Class[i+1];
        }
        printf("删除成功\n");
        output(Class,n-1);
    }
}
double calave(int n,struct Stu Class[],double ave[])
{
    int Language_score_sum=0;
    int Math_score_sum=0;
    int English_score_sum=0;
    int PE_score_sum=0;
    int C_score_sum=0;
    for(int i=0; i<n; i++)
    {
        Language_score_sum+=Class[i].Language_score;
        Math_score_sum+=Class[i].Math_score;
        English_score_sum+=Class[i].English_score;
        PE_score_sum+=Class[i].PE_score;
        C_score_sum+=Class[i].C_score;
    }
    ave[0]=(double)Language_score_sum/n;
    ave[1]=(double)Math_score_sum/n;
    ave[2]=(double)English_score_sum/n;
    ave[3]=(double)PE_score_sum/n;
    ave[4]=(double)C_score_sum/n;
}
void save(int n,struct Stu Class[])
{
    FILE *fp;
    fp = fopen("score_data.txt","w");
    if(fp == NULL)
    {
        printf("error!");
        return;
    }
    else
    {
        for(int j=0; j<n; j++)
        {
            fprintf(fp,"%s %d %d %d %d %d %d %d\n",Class[j].Name,Class[j].Number,Class[j].Language_score,Class[j].Math_score,Class[j].English_score,Class[j].PE_score,Class[j].C_score,Class[j].Sum_score);
        }
        printf("文件写入成功\n");
    }
    fclose(fp);
}
int read(int n,struct Stu Class[])
{
    FILE *fp;
    fp = fopen("score_data.txt","r");
    int count=0;
    if(fp == NULL)
    {
        printf("error!");
        return 0;
    }
    else
    {
        for(int j=0; j<n; j++)
        {
            int flag=fscanf(fp,"%s %d %d %d %d %d %d %d\n",Class[j].Name,&Class[j].Number,&Class[j].Language_score,&Class[j].Math_score,&Class[j].English_score,&Class[j].PE_score,&Class[j].C_score,&Class[j].Sum_score);
            if(flag!=-1) count++;
        }
        printf("文件读取成功\n");
    }
    fclose(fp);
    return count;
}
void menu(struct Stu Class[])
{
    int n=0,count;
    int option=1;
    while(option<=9&&option>=1)
    {
        printf("------------------------\n");
        printf("------学生成绩管理------\n");
        printf("------1.输入成绩  ------\n");
        printf("------2.输出成绩  ------\n");
        printf("------3.按总成绩排序----\n");
        printf("------4.按学号查询成绩--\n");
        printf("------5.修改信息  ------\n");
        printf("------6.删除学生  ------\n");
        printf("------7.计算各科平均分--\n");
        printf("------8.文件读入  ------\n");
        printf("------9.保存至文件------\n");
        printf("------other.退出  ------\n");
        printf("------------------------\n");
        printf("输入选项:");
        scanf("%d",&option);
        switch(option)
        {
            case 1:
            {
                system("cls");
                printf("输入学生的个数(不大于%d):",Max-n);
                scanf("%d",&count);
                while(count--)
                {
                    input(Class,n++);
                }
                output(Class,n);
                break;
            }
            case 2:
            {
                system("cls");
                output(Class,n);
                break;
            }
            case 3:
            {
                system("cls");
                Sort(Class,n);
                output(Class,n);
                break;
            }
            case 4:
            {
                system("cls");
                int number;
                printf("输入要查找的学号:");
                scanf("%d",&number);
                int index=search(number,n,Class);
                if(index==-1)
                {
                    printf("查找失败\n");
                }
                else
                {
                    printf("查找成功\n");
                    outputOne(Class,index);
                }
                break;
            }
            case 5:
            {
                system("cls");
                output(Class,n);
                int number;
                printf("输入要修改成绩的学生对应的学号:");
                scanf("%d",&number);
                modify(number,n,Class);
                output(Class,n);
                break;
            }
            case 6:
            {
                system("cls");
                output(Class,n);
                int number;
                printf("输入要删除的学号:");
                scanf("%d",&number);
                del(number,n,Class);
                n--;
                system("cls");
                output(Class,n);
                break;
            }
            case 7:
            {
                system("cls");
                output(Class,n);
                double ave[obj_num];
                calave(n,Class,ave);
                char str[]="平均分";
                printf("\n");
                printf("%5s",str);
                printf("     ");
                printf("%5.2lf",ave[0]);
                printf("%6.2lf",ave[1]);
                printf("%6.2lf",ave[2]);
                printf("%6.2lf",ave[3]);
                printf("%6.2lf",ave[4]);
                printf("\n");
                break;
            }
            case 8:
            {
                system("cls");
                n-=n; 
                n+=read(Max,Class);
                break;
            }
            case 9:
            {
                system("cls");
                save(n,Class);
                break;
            }
            default :
            {
                break;
            }
        }
    }
}
int main()
{
    struct Stu Class [Max];
    menu(Class);
    return 0;
}