#include <iostream>
#include <stdio.h>
#include <string>
#include <cstring>
#include<math.h> 
#include<io.h>
#include <stdlib.h>
using namespace std;

//定义学生节点
typedef struct studentNode{
    string number;
    string name;
    int math;
    int english;
    int chinese;
    struct studentNode  *next;
}*student;
int countOfStudent;
FILE * fp;
void ShowAllStudentInfo(student& studentLink);
//输入学生信息
void InputStudentInfo(student& studentLink){
    cout << "************欢迎进入学生信息创建菜单*************" << endl;
    cout << "1.重新创建" << endl;
    cout << "2.引用已有数据" << endl;
    int choice = 0;
    int choice1 = 0;
    studentLink->next = nullptr;
    cin >> choice;
    switch (choice){
    case 1:{
               cout << "请依次输入学号,姓名,数学成绩,英语成绩,语文成绩:" << endl;
               countOfStudent = 0;
               while (1){
                   student stu = new studentNode;
                   countOfStudent = countOfStudent + 1;
                   cin >> stu->number >> stu->name >> stu->math >> stu->english >> stu->chinese;
                   cout << stu->number << stu->name << stu->math << stu->english << stu->chinese;
                   //头插法
                   stu->next = studentLink->next;
                   studentLink->next = stu;
                   cout << "1.继续输入        2.已完成" << endl;
                   cin >> choice1;
                   if (choice1 == 2)
                   {
                       //输入完成后将学生信息写入文件
                       fp = fopen("output\\studentFile.txt", "w");
                       fprintf(fp, "%d\n", countOfStudent);
                       student p = studentLink->next;
                       while (p){
                           fprintf(fp, "%s %s %d %d %d \n", p->number.c_str(), p->name.c_str(), p->math, p->english, p->chinese);
                           cout << p->number << p->name << p->math << p->english << p->chinese;
                           p = p->next;
                       }
                       fclose(fp);
                       break;
                   }
                   else{
                       cout << "请依次输入学号,姓名,数学成绩,英语成绩,语文成绩:" << endl;
                   }

               }
               break;
    }
    case 2:
        //到指定文件夹读取数据
        int exists = 0;
        if (!access("output\\studentFile.txt", 0))
            exists = 1;

        char a[20];
        char b[30];
        if (exists)
        {
            fp = fopen("output\\studentFile.txt", "rt");
            fscanf(fp, "%d", &countOfStudent);
            for (int i = 0; i<countOfStudent; i++)
            {
                student stu = new studentNode;
                fscanf(fp, "%s %s %d %d %d\n", b, a, &stu->math, &stu->english, &stu->chinese);
                stu->number = b;
                stu->name = a;
                //头插法
                stu->next = studentLink->next;
                studentLink->next = stu;
            }
            cout << "已加载完成!" << "已加载" << countOfStudent << "条数据!" << endl;
            //cout<<stu1.name<<stu1.number<<stu1.chinese<<stu1.math<<stu1.english<<endl;

        }
        else{
            cout << "暂无本地数据,请手动创建!" << endl;
        }
        fclose(fp);
        break;
    }
}
//显示所有学生信息
void ShowAllStudentInfo(student& studentLink){
    cout << "************欢迎进入学生信息浏览菜单*************" << endl;
    student p = studentLink->next;
    cout << "学号:             " << "姓名:   " << "数学:   " << "英语:  " << "语文:       " << endl;
    while (p){
        cout << p->number << "        " << p->name << "     " << p->math << "       " << p->english << "      " << p->chinese << endl;
        p = p->next;
    }
}
//数据的排序,并显示
void SortAllStudentInfo(student& studentLink){
    cout << "************欢迎进入学生信息顺序显示菜单*************" << endl;
    int choice = 0;
    cout << "1 按学号升序显示         2 按学号降序显示   " << endl;
    cout << "请输入您的选择:" << endl;
    cin >> choice;
    switch (choice){
    case 1:{
               student p;//循环指示变量,用于指向无序表的当前待插入元素
               student q;//q和r用于对已有有序序列进行循环遍历
               student r;
               student u;//临时变量,用于控制循环
               p = studentLink->next;
               studentLink->next = nullptr;
               while (p){
                   //每次循环开始前将指针指向最开始的地方
                   r = studentLink;
                   q = studentLink->next;
                   while ((q != nullptr) && q->number < p->number){
                       r = q;
                       q = q->next;
                   }
                   //保存下一个需插入的点
                   u = p->next;
                   //保存好了之后进行插入
                   p->next = r->next;
                   r->next = p;
                   //插入完成之后,将p指回未排序序列
                   p = u;
               }
               {

               }

               {
                   fp = fopen("output\\studentAscend.txt", "w");
                   cout << "************学生信息升序浏览*************" << endl;
                   student p = studentLink->next;
                   cout << "学号:             " << "姓名:   " << "数学:   " << "英语:  " << "语文:       " << endl;
                   while (p){
                       cout << p->number << "        " << p->name << "     " << p->math << "       " << p->english << "      " << p->chinese << endl;
                       fprintf(fp, "%s %s %d %d %d \n", p->number.c_str(), p->name.c_str(), p->math, p->english, p->chinese);
                       p = p->next;
                   }
               }
               fclose(fp);
               break;
    }
    case 2:{
               student p, q, r, u;
               p = studentLink->next;
               studentLink->next = nullptr;
               while (p){
                   r = studentLink;
                   q = studentLink->next;
                   while ((q != nullptr) && q->number>p->number){
                       r = q;
                       q = q->next;
                   }
                   u = p->next;
                   p->next = r->next;
                   r->next = p;
                   p = u;
               }
               {
                   fp = fopen("output\\studentDescend.txt", "w");
                   cout << "************学生信息降序浏览*************" << endl;
                   student p = studentLink->next;
                   cout << "学号:             " << "姓名:   " << "数学:   " << "英语:  " << "语文:       " << endl;
                   while (p){
                       cout << p->number << "        " << p->name << "     " << p->math << "       " << p->english << "      " << p->chinese << endl;
                       fprintf(fp, "%s %s %d %d %d \n", p->number.c_str(), p->name.c_str(), p->math, p->english, p->chinese);
                       p = p->next;
                   }
               }
               fclose(fp);
               break;
    }

    }

}
//学生信息查询
void SearchStudentInfo(student& studentLink){
    cout << "************欢迎进入学生信息查询菜单*************" << endl;
    while (1)
    {
        cout << "1.按照学号查询。                 2.按照姓名查询" << endl;
        int choice = 0;
        int choice1 = 0;
        cin >> choice;
        switch (choice){
        case 1:
        {
                  student p = studentLink->next;
                  cout << "1.按照学号精确查询。                 2.按照学号模糊查询" << endl;
                  cin >> choice1;
                  switch (choice1){
                  case 1:
                  {
                            cout << "请输入精确学号:" << endl;
                            string num;
                            cin >> num;
                            bool flag = false;
                            while (p){
                                if (p->number == num)
                                {
                                    flag = true;
                                    cout << "学号:             " << "姓名:   " << "数学:   " << "英语:  " << "语文:       " << endl;
                                    cout << p->number << "        " << p->name << "     " << p->math << "       " << p->english << "      " << p->chinese << endl;
                                    break;
                                }
                                p = p->next;
                            }
                            if (!flag)
                            {
                                cout << "当前学号不存在" << endl;
                            }

                            break;
                  }
                  case 2:
                  {
                            cout << "请输入前缀学号:" << endl;
                            string num;
                            bool flag = false;
                            cin >> num;
                            while (p){
                                if (p->number.find(num, 0) == 0)
                                {
                                    if (!flag)
                                    {
                                        cout << "学号:             " << "姓名:   " << "数学:   " << "英语:  " << "语文:       " << endl;
                                    };
                                    cout << p->number << "        " << p->name << "     " << p->math << "       " << p->english << "      " << p->chinese << endl;
                                    flag = true;
                                }
                                p = p->next;
                            }
                            if (!flag)
                            {
                                cout << "当前学号不存在" << endl;
                            }
                            break;
                  }
                  }

                  break; }
        case 2:
        {
                  student p = studentLink->next;
                  cout << "1.按照姓名精确查询。                 2.按照姓氏模糊查询" << endl;
                  cin >> choice1;

                  switch (choice1){
                  case 1:
                  {
                            cout << "请输入精确姓名:" << endl;
                            string name;
                            cin >> name;
                            bool flag = false;
                            while (p){
                                if (p->name == name)
                                {
                                    cout << "学号:             " << "姓名:   " << "数学:   " << "英语:  " << "语文:       " << endl;
                                    cout << p->number << "        " << p->name << "     " << p->math << "       " << p->english << "      " << p->chinese << endl;
                                    flag = true;
                                    break;
                                }

                                p = p->next;
                            }
                            if (!flag)
                            {
                                cout << "当前姓名不存在" << endl;
                            }
                            break;
                  }
                  case 2:
                  {
                            cout << "请输入前缀姓氏:" << endl;
                            string name;
                            bool flag = false;
                            cin >> name;
                            while (p){
                                if (p->name.find(name, 0) == 0)
                                {
                                    if (!flag)
                                    {
                                        cout << "学号:             " << "姓名:   " << "数学:   " << "英语:  " << "语文:       " << endl;
                                    };
                                    cout << p->number << "        " << p->name << "     " << p->math << "       " << p->english << "      " << p->chinese << endl;
                                    flag = true;
                                }
                                p = p->next;
                            }
                            if (!flag)
                            {
                                cout << "当前姓氏不存在" << endl;
                            }
                            break;
                  }
                  }

                  break;
        }

        }
        int choice3 = 0;
        cout << "1.继续查询。                 2.查询完成" << endl;
        cin >> choice3;
        if (choice3 == 2)
        {
            break;
        }
    }

}
//对学生信息进行修改
void ModifyStudentInfo(student& studentLink){
    cout << "************欢迎进入学生信息修改菜单*************" << endl;
    fp = fopen("output\\studentFile.txt", "rt");
    fscanf(fp, "%d", &countOfStudent);
    fclose(fp);
    while (1){
        cout << "1.添加      2.删除      3.修改" << endl;
        int choice = 0;
        cout << "请输入您想要的操作:" << endl;
        cin >> choice;
        switch (choice){
        case 1:
        {

                  cout << "请依次输入学号,姓名,数学成绩,英语成绩,语文成绩:" << endl;
                  while (1){
                      student stu = new studentNode;
                      countOfStudent = countOfStudent + 1;
                      cin >> stu->number >> stu->name >> stu->math >> stu->english >> stu->chinese;
                      cout << stu->number << stu->name << stu->math << stu->english << stu->chinese;
                      //头插法
                      stu->next = studentLink->next;
                      studentLink->next = stu;
                      cout << "1.继续输入        2.已完成" << endl;
                      int  choice1 = 0;
                      cout << "请输入选择:" << endl;
                      cin >> choice1;
                      if (choice1 == 2)
                      {
                          break;
                      }
                  }
                  break;
        }
        case 2:
        {
                  cout << "请输入学生学号" << endl;
                  string number1;
                  cin >> number1;
                  bool flag = false;
                  student p = studentLink;
                  student p1 = p->next;
                  while (p){
                      if (p1)
                      {
                          if (p1->number == number1)
                          {
                              cout << "find" << endl;
                              student p2 = p1;
                              p->next = p2->next;
                              free(p2);
                              flag = true;
                              countOfStudent--;
                          }
                      }
                      p = p->next;
                      if (p)
                      {
                          p1 = p->next;
                      }

                  }
                  if (!flag)
                  {
                      cout << "无此学生!" << endl;
                  }
                  break;
        }
        case 3:
        {
                  cout << "请输入需修改学生的学号:" << endl;
                  string number;
                  cin >> number;
                  bool flag = false;
                  student p = studentLink->next;
                  while (p){
                      if (p->number == number)
                      {
                          flag = true;
                          cout << "1 修改学号 2 修改姓名 3 修改数学成绩 4 修改英语成绩 5 修改英语成绩" << endl;
                          int cho = 0;
                          cin >> cho;
                          switch (cho){
                          case 1:{

                                     cout << "请输入新的学号:" << endl;
                                     string num;
                                     cin >> num;
                                     p->number = num;
                                     break;
                          }
                          case 2:{
                                     cout << "请输入新的姓名:" << endl;
                                     string name;
                                     cin >> name;
                                     p->name = name;
                                     break;
                          }
                          case 3:{
                                     cout << "请输入新的数学成绩:" << endl;
                                     int num;
                                     cin >> num;
                                     p->math = num;
                                     break;
                          }
                          case 4:{
                                     cout << "请输入新的英语成绩:" << endl;
                                     int num;
                                     cin >> num;
                                     p->english = num;
                                     break;
                          }
                          case 5:{
                                     cout << "请输入新的语文成绩:" << endl;
                                     int num;
                                     cin >> num;
                                     p->chinese = num;
                                     break;
                          }
                          }
                      }
                      p = p->next;
                  }
                  if (!flag)
                  {
                      cout << "该学号不存在" << endl;
                  }
                  break;
        }
        }
        cout << "1 继续修改      2 修改完成" << endl;
        int choice7 = 0;
        cin >> choice7;
        if (choice7 == 2)
        {
            student p = studentLink->next;
            cout << "sssssss" << endl;
            //输入完成后将学生信息写入文件
            fp = fopen("output\\studentFile.txt", "w");
            fprintf(fp, "%d\n", countOfStudent);

            while (p){
                fprintf(fp, "%s %s %d %d %d \n", p->number.c_str(), p->name.c_str(), p->math, p->english, p->chinese);

                p = p->next;
            }
            fclose(fp);
            break;
        }
    }
}
//数据统计功能

void StatisticStudentInfo(student& studentLink){
    cout << "1 学生平均分及总分         2 每门课程平均分机最高分最低分" << endl;
    int choice = 0;
    cout << "请输入您的选择:" << endl;
    cin >> choice;
    switch (choice){
    case 1:
    {
              //计算每个学生的平均分和总分
              fp = fopen("output\\studentAverageScoreAndTotal.txt", "wb");
              student p = studentLink->next;
              int avg = 0;
              int total = 0;
              cout << "学号:          " << "姓名:     " << "平均分:            " << "总分:        " << endl;
              while (p){
                  avg = (p->math + p->english + p->chinese) / 3;
                  total = p->math + p->english + p->chinese;
                  fprintf(fp, "%s  %s  %ld  %ld\n", p->number.c_str(), p->name.c_str(), avg, total);

                  cout << p->number << "      " << p->name << "           " << avg << "          " << total << endl;
                  p = p->next;
              }
              fclose(fp);

              break;
    }
    case 2:
    {
              int mathMax = 0; int mathMin = 65535; int mathAvg = 0;
              int englishMax = 0; int englishMin = 65535; int englishAvg = 0;
              int chineseMax = 0; int chinesMin = 65535; int chineseAvg = 0;
              int countOfM = 0;
              student p = studentLink->next;
              while (p){
                  //遍历数学成绩
                  if (p->math>mathMax){
                      mathMax = p->math;
                  }
                  if (p->math<mathMin){
                      mathMin = p->math;
                  }
                  mathAvg += p->math;
                  if (p->english>englishMax)
                  {
                      englishMax = p->english;
                  }
                  if (p->english<englishMin)
                  {
                      englishMin = p->english;
                  }
                  englishAvg += p->english;
                  if (p->chinese >chineseMax)
                  {
                      chineseMax = p->chinese;
                  }
                  if (p->chinese<chinesMin)
                  {
                      chinesMin = p->chinese;
                  }
                  chineseAvg += p->chinese;
                  countOfM++;
                  p = p->next;
              }
              fp = fopen("output\\studentMath.txt", "wb");
              fprintf(fp, "数学:    最高分:%d  最低分:   %d      平均分:    %d\n", mathMax, mathMin, mathAvg / countOfM);
              cout << "数学:          " << "最高分:   " << mathMax << "   最低分:  " << mathMin << "   平均分:   " << mathAvg / countOfM << endl;

              fclose(fp);

              fp = fopen("output\\studentEglish.txt", "wb");
              fprintf(fp, "英语:    最高分:%d  最低分:   %d      平均分:    %d\n", englishMax, englishMin, englishAvg / countOfM);
              cout << "英语:          " << "最高分:   " << englishMax << "   最低分:  " << englishMax << "   平均分:   " << englishAvg / countOfM << endl;
              fclose(fp);

              fp = fopen("output\\studentChinese.txt", "wb");
              fprintf(fp, "语文:    最高分:%d  最低分:   %d      平均分:    %d\n", chineseMax, chinesMin, chineseAvg / countOfM);
              cout << "语文:          " << "最高分:   " << chineseMax << "   最低分:  " << chinesMin << "   平均分:   " << chineseAvg / countOfM << endl;
              fclose(fp);
              break;

    }
    }
}
int main(){
    cout << "****************************欢迎来到学生信息管理系统***************************" << endl;
    cout << "1.输入学生信息" << endl;
    cout << "2.查询所有学生信息" << endl;
    cout << "3.排序显示学生信息" << endl;
    cout << "4.查询某一个学生具体信息" << endl;
    cout << "5.插入新信息,修改信息,删除信息" << endl;
    cout << "6.数据统计" << endl;
    cout << "7.退出" << endl;
    int choice = 0;
    student studentLink = new studentNode;
    //studentLink->next = nullptr;
    while (1){
        cout << "主菜单---请输入您的选择:";
        cin >> choice;
        switch (choice){
        case 1:
            InputStudentInfo(studentLink);
            break;
        case 2:
            ShowAllStudentInfo(studentLink);
            break;
        case 3:
            SortAllStudentInfo(studentLink);
            break;
        case 4:
            SearchStudentInfo(studentLink);
            break;
        case 5:
            ModifyStudentInfo(studentLink);
            break;
        case 6:
            StatisticStudentInfo(studentLink);
            break;
        case 7:
            exit(0);
            break;
        }
    }
    getchar();
    return 0;
}