C语言程序设计实训:基于链表的学生信息管理系统

作者声明:千余行均为原创,使用转载请告知本人,运行环境clion2023.2+Mingw64.

*main函数:以菜单形式将各项功能提供给用户,根据用户的选择,调用相应的函数。

*定义函数CreateList:按学号由小到大,建立有序的链表。逆序输入 n 个学生信息(调用n次input),学号大的先输入,建立带头结点的单链表。

*定义函数Output:以指向某个学生结点的指针为参数,将学生信息格式化输出

*定义函数Save:将某个学生信息存入文件

*定义函数Fetch:从文件中随机读取某个学生的信息

*定义函数Search_num:查找指定学号的学生,返回指向该学生结点的指针

*定义函数InsertList:在函数中输入一个学生的信息,将该学生信息插入到链表中的相应位置,并保持此链表按学号的有序性

*定义函数Delete_num:从链表中删除指定学号的学生。

定义函数Search_major _subject_score:查找某个专业的、某门课程的成绩小于某个分数的学生,返回指向该学生结点的指针。

定义函数Delete_ major _subject:从链表中删除某个专业的、某门课程的成绩小于某个分数的学生。

 

//
// Created by 孙伟豪 on 2024/7/8.
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <algorithm>
#include<string>

typedef struct HNode{
    char num[15];//学号
    char name[15];//姓名
    char major[10];//专业
    int classNo;//班级(1-2)
    int score[3];//3门课的成绩(0-2)
    struct HNode *next;//指针域
}student,*HLink;

// 从文件中读取数据构建链表,尾插法,文件是从小到大
HLink createStudentListFromFile(const char *filename) {
    FILE *fp;
    HLink head = (HLink)malloc(sizeof(student));
    HLink tail = head;
    head->next = NULL;

    fp = fopen(filename, "r");
    if (fp == NULL) {
        perror("Error opening file");
        exit(EXIT_FAILURE);
    }

    // 从文件中读取数据,每次读取一行存储一个学生信息
    char line[100];
    while (fgets(line, sizeof(line), fp) != NULL) {
        // 解析读取的一行数据,假设格式为 "学号 姓名 专业 班级 成绩1 成绩2 成绩3"
        student *newNode = (student *)malloc(sizeof(student));
        sscanf(line, "%s %s %s %d %d %d %d",
               newNode->num, newNode->name, newNode->major,
               &newNode->classNo, &newNode->score[0], &newNode->score[1], &newNode->score[2]);
        newNode->next = NULL;

        // 将新节点加入链表尾部
        tail->next = newNode;
        tail = newNode;
    }

    fclose(fp);
    return head;
}

// 输出链表中的学生信息
void printStudentList(HLink head) {
    HLink p = head->next;  // 跳过头结点
    while (p != NULL) {
        printf("学号:%s 姓名:%s 专业:%s 班级:%d 成绩:%d %d %d\n",
               p->num, p->name, p->major, p->classNo,
               p->score[0], p->score[1], p->score[2]);
        p = p->next;
    }
}

// 创建带头节点的链表(逆序输入,头插法)
HLink CreateListReverse(int n) {
    HLink head = (HLink)malloc(sizeof(student)); // 创建 头结点,这里使用了名叫head的局部变量,最好使用其他局部变量,避免歧义
    if (head == NULL) {
        printf("内存分配失败\n");
        exit(1);
    }
    head->next = NULL; // 初始为空链表

    printf("请输入%d个学生的信息(学号 姓名 专业 班级 成绩1 成绩2 成绩3):\n", n);
    printf("注意输入格式,一共七个数据输入,不要输入错误或者输入少,否则会运行失败!\n", n);
    for (int i = 0; i < n; ++i) {
        HLink newNode = (HLink)malloc(sizeof(student)); // 创建 新节点
        if (newNode == NULL) {
            printf("内存分配失败\n");
            exit(1);
        }

        printf("学生%d:\n", i + 1);
        scanf("%s %s %s %d %d %d %d", newNode->num, newNode->name, newNode->major,
              &newNode->classNo, &newNode->score[0], &newNode->score[1], &newNode->score[2]);

        newNode->next = head->next; // 将新节点插入链表头部,这里是头插法的内容
        head->next = newNode;
    }

    return head;
}

// 输出单个学生信息及其之后的所有学生信息
void Output(HLink head, int n) {
    int count = 0;
    HLink temp = head->next;

    // 定位指针在输出节点
    while (temp != NULL && count < n - 1) {
        temp = temp->next;
        count++;
    }

    if (temp != NULL) {
        printf("学号:%s 姓名:%s 专业:%s 班级:%d 成绩:%d %d %d\n",
               temp->num, temp->name, temp->major, temp->classNo,
               temp->score[0], temp->score[1], temp->score[2]);

        // 输出之后的所有学生信息
        temp = temp->next;
        while (temp != NULL) {
            printf("学号:%s 姓名:%s 专业:%s 班级:%d 成绩:%d %d %d\n",
                   temp->num, temp->name, temp->major, temp->classNo,
                   temp->score[0], temp->score[1], temp->score[2]);
            temp = temp->next;
        }
    } else {
        printf("链表中没有第%d个学生\n", n);
    }
}

void Output2(HLink head, int n) {
    int count = 0;
    int s=0;
    HLink temp = head->next;

    while (temp != NULL && count < n - 1) {
        temp = temp->next;
        count++;
    }

    if (temp != NULL) {
        printf("学号:%s 姓名:%s 专业:%s 班级:%d 成绩:%d %d %d\n",
               temp->num, temp->name, temp->major, temp->classNo,
               temp->score[0], temp->score[1], temp->score[2]);

        // 输出之后的所有学生信息
        temp = temp->next;
        while (temp != NULL) {
            printf("学号:%s 姓名:%s 专业:%s 班级:%d 成绩:%d %d %d\n",
                   temp->num, temp->name, temp->major, temp->classNo,
                   temp->score[0], temp->score[1], temp->score[2]);
            temp = temp->next;
        }
    } else {
        printf("链表中没有第%d个学生\n", n);
    }
    temp = head->next;

    if (s != n-1) {
        printf("学号:%s 姓名:%s 专业:%s 班级:%d 成绩:%d %d %d\n",
               temp->num, temp->name, temp->major, temp->classNo,
               temp->score[0], temp->score[1], temp->score[2]);

        // 输出之后的所有学生信息
        s++;
        temp = temp->next;
        while (s!=n-1) {
            printf("学号:%s 姓名:%s 专业:%s 班级:%d 成绩:%d %d %d\n",
                   temp->num, temp->name, temp->major, temp->classNo,
                   temp->score[0], temp->score[1], temp->score[2]);
            temp = temp->next;
            s++;
        }
    }

}


// 将第n个学生信息保存到文件"student2.txt"
void Save(HLink head, int n) {
    int count = 0;
    HLink temp = head->next;

    // 定位到第n个学生
    while (temp != NULL && count < n - 1) {
        temp = temp->next;
        count++;
    }

    if (temp != NULL) {
        FILE *fp;
        fp = fopen("student2.txt", "w"); // 打开文件以写入方式

        if (fp == NULL) {
            printf("无法打开文件\n");
            return;
        }

        // 写入第n个学生的信息到文件
        fprintf(fp, "学号:%s\n姓名:%s\n专业:%s\n班级:%d\n成绩:%d %d %d\n",
                temp->num, temp->name, temp->major, temp->classNo,
                temp->score[0], temp->score[1], temp->score[2]);

        fclose(fp);
        printf("第%d个学生信息已成功保存到文件student2.txt\n", n);
    } else {
        printf("链表中没有第%d个学生\n", n);
    }
}

// 将全部学生信息保存到文件"student3.txt"
void Save2(HLink head) {
    FILE *fp;
    fp = fopen("student3.txt", "w"); // 打开文件以  写入方式w

    if (fp == NULL) {
        printf("无法打开文件\n");
        return;
    }

    HLink temp = head->next;

    while (temp != NULL) {
        // 写入学生信息到文件
        fprintf(fp, "%s %s %s %d %d %d %d\n",
                temp->num, temp->name, temp->major, temp->classNo,
                temp->score[0], temp->score[1], temp->score[2]);

        temp = temp->next;
    }

    fclose(fp);
    printf("全部学生信息已成功保存到文件student3.txt\n");
}

// 从文件读取学生信息并存储到链表中
HLink ReadFromFile(char *filename) {
    FILE *fp;
    fp = fopen(filename, "r");

    if (fp == NULL) {
        printf("无法打开文件 %s\n", filename);
        return NULL;
    }

    HLink head = (HLink)malloc(sizeof(student));
    head->next = NULL;
    HLink current = head;

    char num[15];
    char name[15];
    char major[10];
    int classNo;
    int score1, score2, score3;

    while (fscanf(fp, "%s %s %s %d %d %d %d\n", num, name, major, &classNo, &score1, &score2, &score3) != EOF) {
        HLink newNode = (HLink)malloc(sizeof(student));
        strcpy(newNode->num, num);
        strcpy(newNode->name, name);
        strcpy(newNode->major, major);
        newNode->classNo = classNo;
        newNode->score[0] = score1;
        newNode->score[1] = score2;
        newNode->score[2] = score3;
        newNode->next = NULL;

        current->next = newNode;
        current = newNode;
    }

    fclose(fp);
    return head;
}

// 随机选择一个学生并输出其信息
void PrintRandomStudent(HLink head) {
    if (head == NULL || head->next == NULL) {
        printf("链表为空,无法选择学生\n");
        return;
    }

    // 计算链表长度
    int count = 0;
    HLink temp = head->next;
    while (temp != NULL) {
        count++;
        temp = temp->next;
    }

    // 生成随机数选择一个学生
    srand(time(NULL));
    int randomIndex = rand() % count;

    // 找到对应学生节点
    temp = head->next;
    int currentIndex = 0;
    while (temp != NULL && currentIndex < randomIndex) {
        currentIndex++;
        temp = temp->next;
    }

    // 输出学生信息
    if (temp != NULL) {
        printf("随机选择的学生信息:\n");
        printf("学号:%s\n", temp->num);
        printf("姓名:%s\n", temp->name);
        printf("专业:%s\n", temp->major);
        printf("班级:%d\n", temp->classNo);
        printf("成绩:%d %d %d\n", temp->score[0], temp->score[1], temp->score[2]);
    } else {
        printf("未找到对应学生\n");
    }
}

HLink Search_num(HLink head, char *numToFind) {
    if (head == NULL || head->next == NULL) {
        printf("链表为空,无法查找学生\n");
        return NULL;
    }

    HLink temp = head->next;
    while (temp != NULL) {
        if (strcmp(temp->num, numToFind) == 0) {
            printf("找到指定学号的学生信息:\n");
            printf("学号:%s\n", temp->num);
            printf("姓名:%s\n", temp->name);
            printf("专业:%s\n", temp->major);
            printf("班级:%d\n", temp->classNo);
            printf("成绩:%d %d %d\n", temp->score[0], temp->score[1], temp->score[2]);
            return temp; // 返回指向该学生节点的指针
        }
        temp = temp->next;
    }

    printf("未找到学号为 %s 的学生\n", numToFind);
    return NULL;
}

// 插入一个学生信息并保持链表有序
void InsertList(HLink head, char *num, char *name, char *major, int classNo, int score1, int score2, int score3) {
    HLink newNode = (HLink)malloc(sizeof(student));
    strcpy(newNode->num, num);
    strcpy(newNode->name, name);
    strcpy(newNode->major, major);
    newNode->classNo = classNo;
    newNode->score[0] = score1;
    newNode->score[1] = score2;
    newNode->score[2] = score3;
    newNode->next = NULL;

    HLink current = head;
    while (current->next != NULL && strcmp(current->next->num, num) < 0) {
        current = current->next;
    }

    newNode->next = current->next;
    current->next = newNode;

    printf("成功插入学生信息:\n");
    printf("学号:%s\n", newNode->num);
    printf("姓名:%s\n", newNode->name);
    printf("专业:%s\n", newNode->major);
    printf("班级:%d\n", newNode->classNo);
    printf("成绩:%d %d %d\n", newNode->score[0], newNode->score[1], newNode->score[2]);
}

// 删除指定学号的学生节点
void Delete_num(HLink head, char *numToDelete) {
    if (head == NULL || head->next == NULL) {
        printf("链表为空,无法删除学生\n");
        return;
    }

    HLink current = head;
    while (current->next != NULL && strcmp(current->next->num, numToDelete) != 0) {
        current = current->next;
    }

    if (current->next == NULL) {
        printf("未找到学号为 %s 的学生,无法删除\n", numToDelete);
        return;
    }

    HLink temp = current->next;
    current->next = temp->next;
    free(temp);

    printf("成功删除学号为 %s 的学生\n", numToDelete);
}

// 查找某个专业的、某门课程的成绩小于某个分数的学生,并返回符合条件的学生链表的头指针, 这里注意:整个新链表都有数据
HLink Search_major_subject_score(HLink head, char *major, int subjectIndex, int maxScore) {
    if (head == NULL || head->next == NULL) {
        printf("链表为空,无法查找学生\n");
        return NULL;
    }

    HLink resultHead = NULL;  // 结果链表的头指针
    HLink resultTail = NULL;  // 结果链表的尾指针

    HLink temp = head->next;

    while (temp != NULL) {
        if (strcmp(temp->major, major) == 0 && temp->score[subjectIndex] < maxScore) {
            HLink newNode = (HLink)malloc(sizeof(student));
            strcpy(newNode->num, temp->num);
            strcpy(newNode->name, temp->name);
            strcpy(newNode->major, temp->major);
            newNode->classNo = temp->classNo;
            newNode->score[0] = temp->score[0];
            newNode->score[1] = temp->score[1];
            newNode->score[2] = temp->score[2];
            newNode->next = NULL;

            if (resultHead == NULL) {
                resultHead = newNode;
                resultTail = newNode;
            } else {
                resultTail->next = newNode;
                resultTail = newNode;
            }
        }
        temp = temp->next;
    }

    if (resultHead == NULL) {
        printf("未找到符合条件的学生\n");
    }

    return resultHead;
}

// 查找某个专业的、某门课程的成绩小于某个分数的学生,并返回符合条件的学生链表的头指针
HLink Search_major_subject_score2(HLink head, char *major, int subjectIndex, int maxScore) {
    if (head == NULL || head->next == NULL) {
        printf("链表为空,无法查找学生\n");
        return NULL;
    }

    HLink resultHead = NULL;  // 结果链表的头指针
    HLink resultTail = NULL;  // 结果链表的尾指针

    HLink temp = head->next;

    while (temp != NULL) {
        if (strcmp(temp->major, major) == 0 && temp->score[subjectIndex] > maxScore) {
            HLink newNode = (HLink)malloc(sizeof(student));
            strcpy(newNode->num, temp->num);
            strcpy(newNode->name, temp->name);
            strcpy(newNode->major, temp->major);
            newNode->classNo = temp->classNo;
            newNode->score[0] = temp->score[0];
            newNode->score[1] = temp->score[1];
            newNode->score[2] = temp->score[2];
            newNode->next = NULL;

            if (resultHead == NULL) {
                resultHead = newNode;
                resultTail = newNode;
            } else {
                resultTail->next = newNode;
                resultTail = newNode;
            }
        }
        temp = temp->next;
    }

    if (resultHead == NULL) {
        printf("未找到符合条件的学生\n");
    }

    return resultHead;
}

// 打印查找后符合条件的部分学生信息链表的函数
void PrintStudentList(HLink head) {
    HLink temp = head;  // head节点是头结点,跳过

    while (temp != NULL) {
        printf("学号:%s 姓名:%s 专业:%s 班级:%d 成绩:%d %d %d\n",
               temp->num, temp->name, temp->major, temp->classNo,
               temp->score[0], temp->score[1], temp->score[2]);
        temp = temp->next;
    }
}

void Delete_major_subject(HLink head, char *major, int subject_index, int max_score) {
    if (head == NULL || head->next == NULL) {
        printf("链表为空或只有头结点,无法进行删除操作。\n");
        return;
    }

    HLink prev = head;
    HLink current = head->next;  // 跳过头结点

    while (current != NULL) {
        if (strcmp(current->major, major) == 0 && current->score[subject_index] < max_score) {
            // 删除符合条件的节点
            prev->next = current->next;
            free(current);
            current = prev->next;
        } else {
            prev = current;
            current = current->next;
        }
    }
}

void Delete_major_subject2(HLink head, char *major, int subject_index, int max_score) {
    if (head == NULL || head->next == NULL) {
        printf("链表为空或只有头结点,无法进行删除操作。\n");
        return;
    }

    HLink prev = head;
    HLink current = head->next;  // 跳过头结点

    while (current != NULL) {
        if (strcmp(current->major, major) == 0 && current->score[subject_index] > max_score) {
            // 删除符合条件的节点
            prev->next = current->next;
            free(current);
            current = prev->next;
        } else {
            prev = current;
            current = current->next;
        }
    }
}

// 查找某门课成绩最高的学生
HLink findMaxScoreStudent(HLink head, int courseIndex) {
    if (head == NULL) {
        printf("链表为空,无法查找。\n");
        return NULL;
    }

    HLink p = head->next;
    HLink maxStudent = NULL;
    int maxScore = -1;  // 初始化为一个较小的值

    while (p != NULL) {
        if (p->score[courseIndex] > maxScore) {
            maxScore = p->score[courseIndex];
            maxStudent = p;
        }
        p = p->next;
    }

    return maxStudent;
}

// 查找某门课成绩最低的学生
HLink findMinScoreStudent(HLink head, int courseIndex) {
    if (head == NULL) {
        printf("链表为空,无法查找。\n");
        return NULL;
    }

    HLink p = head->next;
    //printf("%d\n",p->score[courseIndex]);
    //printStudentList(p);
    HLink minStudent = NULL;
    int minScore = 101;  // 初始化为一个较大的值
    //printf("%d\n",minScore );
    while (p != NULL) {
        //printf("%d\n",minScore );
        if (p->score[courseIndex] < minScore) {
            //printf("%d\n",p->score[courseIndex]);
            //printf("%d\n",minScore );
            minScore = p->score[courseIndex];
            //printf("%d\n",minScore );
            minStudent = p;
        }
        p = p->next;
    }

    return minStudent;
}

// 查找平均分最高的学生
HLink findMaxAverageStudent(HLink head) {
    if (head == NULL) {
        printf("链表为空,无法查找。\n");
        return NULL;
    }

    HLink p = head->next;
    HLink maxStudent = NULL;
    float maxAverage = -1.0;  // 初始化为一个较小的值

    while (p != NULL) {
        float average = (p->score[0] + p->score[1] + p->score[2]) / 3.0;
        if (average > maxAverage) {
            maxAverage = average;
            maxStudent = p;
        }
        p = p->next;
    }

    return maxStudent;
}

// 查找平均分最低的学生
HLink findMinAverageStudent(HLink head) {
    if (head == NULL) {
        printf("链表为空,无法查找。\n");
        return NULL;
    }

    HLink p = head->next;
    HLink minStudent = NULL;
    float minAverage = 101.0;  // 初始化为一个较大的值

    while (p != NULL) {
        float average = (p->score[0] + p->score[1] + p->score[2]) / 3.0;
        if (average < minAverage) {
            minAverage = average;
            minStudent = p;
        }
        p = p->next;
    }

    return minStudent;
}

// 按指定课程成绩排序链表
void sortByCourseScore(HLink head, int courseIndex) {
    if (head == NULL || head->next == NULL) {
        // 如果链表为空或只有一个节点,无需排序
        return;
    }

    HLink current = head->next;
    HLink index = NULL;
    int tempScore;
    char tempNum[15], tempName[15], tempMajor[10];
    int tempClassNo;

    while (current != NULL) {
        index = current->next;

        while (index != NULL) {
            // 比较两个节点的指定课程成绩,根据需要交换节点位置
            if (current->score[courseIndex] > index->score[courseIndex]) {
                // 交换学号
                strcpy(tempNum, current->num);
                strcpy(current->num, index->num);
                strcpy(index->num, tempNum);

                // 交换姓名
                strcpy(tempName, current->name);
                strcpy(current->name, index->name);
                strcpy(index->name, tempName);

                // 交换专业
                strcpy(tempMajor, current->major);
                strcpy(current->major, index->major);
                strcpy(index->major, tempMajor);

                // 交换班级
                tempClassNo = current->classNo;
                current->classNo = index->classNo;
                index->classNo = tempClassNo;

                // 交换成绩
                tempScore = current->score[0];
                current->score[0] = index->score[0];
                index->score[0] = tempScore;

                tempScore = current->score[1];
                current->score[1] = index->score[1];
                index->score[1] = tempScore;

                tempScore = current->score[2];
                current->score[2] = index->score[2];
                index->score[2] = tempScore;
            }
            index = index->next;
        }
        current = current->next;
    }
}

// 按指定课程成绩降序排序链表
void sortByCourseScoreDescending(HLink head, int courseIndex) {
    if (head == NULL || head->next == NULL) {
        // 如果链表为空或只有一个节点,无需排序
        return;
    }

    HLink current = head->next;
    HLink index = NULL;
    int tempScore;
    char tempNum[15], tempName[15], tempMajor[10];
    int tempClassNo;

    while (current != NULL) {
        index = current->next;

        while (index != NULL) {
            // 比较两个节点的指定课程成绩,根据需要交换节点位置(降序)
            if (current->score[courseIndex] < index->score[courseIndex]) {
                // 交换学号
                strcpy(tempNum, current->num);
                strcpy(current->num, index->num);
                strcpy(index->num, tempNum);

                // 交换姓名
                strcpy(tempName, current->name);
                strcpy(current->name, index->name);
                strcpy(index->name, tempName);

                // 交换专业
                strcpy(tempMajor, current->major);
                strcpy(current->major, index->major);
                strcpy(index->major, tempMajor);

                // 交换班级
                tempClassNo = current->classNo;
                current->classNo = index->classNo;
                index->classNo = tempClassNo;

                // 交换成绩
                tempScore = current->score[0];
                current->score[0] = index->score[0];
                index->score[0] = tempScore;

                tempScore = current->score[1];
                current->score[1] = index->score[1];
                index->score[1] = tempScore;

                tempScore = current->score[2];
                current->score[2] = index->score[2];
                index->score[2] = tempScore;
            }
            index = index->next;
        }
        current = current->next;
    }
}

// 打印链表
void printList1(HLink head) {
    HLink temp = head->next;
    while (temp != NULL) {
        printf("学号:%s, 姓名:%s, 专业:%s, 班级:%d, 成绩:%d, %d, %d\n",
               temp->num, temp->name, temp->major, temp->classNo,
               temp->score[0], temp->score[1], temp->score[2]);
        temp = temp->next;
    }
}

// 按平均成绩升序排序链表
void sortByAverageScoreAscending(HLink head) {
    if (head == NULL || head->next == NULL) {
        // 如果链表为空或只有一个节点,无需排序
        return;
    }

    HLink current = head->next;
    HLink index = NULL;
    float currentAvg, indexAvg;
    char tempNum[15], tempName[15], tempMajor[10];
    int tempClassNo, tempScore[3];

    while (current != NULL) {
        index = current->next;

        while (index != NULL) {
            // 计算平均成绩
            currentAvg = (current->score[0] + current->score[1] + current->score[2]) / 3.0;
            indexAvg = (index->score[0] + index->score[1] + index->score[2]) / 3.0;

            // 比较平均成绩,根据需要交换节点位置(升序)
            if (currentAvg > indexAvg) {
                // 交换学号
                strcpy(tempNum, current->num);
                strcpy(current->num, index->num);
                strcpy(index->num, tempNum);

                // 交换姓名
                strcpy(tempName, current->name);
                strcpy(current->name, index->name);
                strcpy(index->name, tempName);

                // 交换专业
                strcpy(tempMajor, current->major);
                strcpy(current->major, index->major);
                strcpy(index->major, tempMajor);

                // 交换班级
                tempClassNo = current->classNo;
                current->classNo = index->classNo;
                index->classNo = tempClassNo;

                // 交换成绩
                memcpy(tempScore, current->score, sizeof(tempScore));
                memcpy(current->score, index->score, sizeof(tempScore));
                memcpy(index->score, tempScore, sizeof(tempScore));
            }
            index = index->next;
        }
        current = current->next;
    }
}

// 按平均成绩降序排序链表
void sortByAverageScoreDescending(HLink head) {
    if (head == NULL || head->next == NULL) {
        // 如果链表为空或只有一个节点,无需排序
        return;
    }

    HLink current = head->next;
    HLink index = NULL;
    float currentAvg, indexAvg;
    char tempNum[15], tempName[15], tempMajor[10];
    int tempClassNo, tempScore[3];

    while (current != NULL) {
        index = current->next;

        while (index != NULL) {
            // 计算平均成绩
            currentAvg = (current->score[0] + current->score[1] + current->score[2]) / 3.0;
            indexAvg = (index->score[0] + index->score[1] + index->score[2]) / 3.0;

            // 比较平均成绩,根据需要交换节点位置(降序)
            if (currentAvg < indexAvg) {
                // 交换学号
                strcpy(tempNum, current->num);
                strcpy(current->num, index->num);
                strcpy(index->num, tempNum);

                // 交换姓名
                strcpy(tempName, current->name);
                strcpy(current->name, index->name);
                strcpy(index->name, tempName);

                // 交换专业
                strcpy(tempMajor, current->major);
                strcpy(current->major, index->major);
                strcpy(index->major, tempMajor);

                // 交换班级
                tempClassNo = current->classNo;
                current->classNo = index->classNo;
                index->classNo = tempClassNo;

                // 交换成绩
                memcpy(tempScore, current->score, sizeof(tempScore));
                memcpy(current->score, index->score, sizeof(tempScore));
                memcpy(index->score, tempScore, sizeof(tempScore));
            }
            index = index->next;
        }
        current = current->next;
    }
}

// 打印链表
void printList2(HLink head) {
    HLink temp = head->next;
    while (temp != NULL) {
        printf("学号:%s, 姓名:%s, 专业:%s, 班级:%d, 成绩:%d, %d, %d, 平均成绩:%.2f\n",
               temp->num, temp->name, temp->major, temp->classNo,
               temp->score[0], temp->score[1], temp->score[2],(temp->score[0]+temp->score[1]+temp->score[2])/3.0);
        temp = temp->next;
    }
}

// 修改学生的成绩
void modifyScore(HLink head, char studentNum[], int courseNum, int newScore) {
    HLink temp = head;
    while (temp != NULL) {
        if (strcmp(temp->num, studentNum) == 0) {
            if (courseNum >= 0 && courseNum < 3) {
                temp->score[courseNum] = newScore;
                printf("修改学号为 %s 的学生的第 %d 门课程成绩为 %d\n", studentNum, courseNum + 1, newScore);
                return;
            } else {
                printf("课程序号超出范围\n");
                return;
            }
        }
        temp = temp->next;
    }
    printf("未找到学号为 %s 的学生\n", studentNum);
}


int main(){
    int cishu=5;
    int r;
    char e[15];
    HLink head = (HLink)malloc(sizeof(student));
    head->next = NULL;  // 头结点初始为空链表

    while (1) {
        printf("请输入用户swh的密码:\n");
        scanf("%s", e);
        while (cishu != 0) {
            if (strcmp(e, "swh040527") == 0) {
                printf("登陆成功!\n");
                cishu=1;
                break;
            } else {
                cishu--;
                if (cishu == 0) {
                    break;
                    printf("登录失败,请等待30s后重新登陆!\n");
                }
                printf("密码错误,请重新登录\n");
                printf("您还有%d次机会\n", cishu);
                printf("请输入用户swh的密码:\n");
                scanf("%s", e);
            }
        }
        if (cishu == 0) {
            printf("登录失败,请等待30s后重新登陆!\n");
            break;
        }
        break;
    }

    while (1){
        if (cishu == 0) {
            break;
        }
        int a;
        printf("-----------------------------------------------------------\n");
        printf("欢迎来到****大学学生信息管理系统\n");
        printf("请输入数字选择相应功能\n");
        printf("1:手动输入学生信息(学号,姓名,专业,班级,3门成绩),学号大的先输入\n");
        printf("2:用文件输入学生信息\n");
        printf("3:从第n个学生开始输出学生信息(0-9)\n");
        printf("4:保存学生信息到文件\n");
        printf("5:将某个学生信息存入文件\n");
        printf("6:从文件中随机读取某个学生信息\n");
        printf("7:查找指定学号的学生\n");
        printf("8:查找某门课成绩最高最低的学生\n");
        printf("9:查找平均分最高最低的学生\n");
        printf("10:按某门课成绩排序\n");
        printf("11:按平均分成绩排序\n");
        printf("12:修改某个学生成绩\n");
        printf("13:输入一个新的学生数据并按序插入\n");
        printf("14:删除指定学号的学生数据\n");
        printf("15:按专业及分数查找指定学生\n");
        printf("16:按专业及分数删除指定学生\n");
        printf("17:退出系统\n");
        printf("请输入序号:\n");
        scanf("%d",&a);
        if ((a < 1) || (a > 17))
            printf("你的输入有误,请重新输入\n");
        switch (a){
            case 1:{

                int n;
                printf("请输入学生的数量:");
                scanf("%d", &n);
                while(n<=0){
                    printf("输入错误,请重新输入\n");
                    printf("请输入学生的数量:");
                    scanf("%d", &n);

                }

                head = CreateListReverse(n);
                printStudentList(head);
                break;
            }

            case 2:{
                // 从文件中读取数据构建链表
                head = createStudentListFromFile("studentInit.txt");

                // 输出链表中的学生信息
                printf("学生信息如下:\n");
                printStudentList(head);
                break;
            }

            case 3:{
                int n,m,p ; // 输出第n个学生的信息及其之后所有学生的信息
                printf("你要输出全部学生信息吗(1:是2:不是):\n");
                scanf("%d",&p);
                printf("你要从第几个学生开始输出(0-9):\n");
                scanf("%d",&m);
                n=m+1;
                if (p==2){
                    Output(head, n);
                }
                if (p==1){
                    Output2(head, n);
                }
                break;
            }

            case 4:{
                Save2(head);
                break;
            }

            case 5:{
                int n;
                // 没有统一输入的学生标记从0开始,自己注意
                printf("请选择你要保存第几个学生的数据,从1开始1-10:\n");
                scanf("%d",&n);
                while((n<=0)||(n>=11)){
                    printf("你的输入有误,请重新输入");
                    printf("请选择你要保存第几个学生的数据,这里从1开始1-10:\n");
                    scanf("%d",&n);
                }
                Save(head, n);
                break;
            }

            case 6:{
                HLink head2 = ReadFromFile("student3.txt");

                // 输出随机选择的学生信息
                PrintRandomStudent(head2);
                break;
            }

            case 7:{
                char numToFind[15];
                printf("\n请输入要查找的学号:");
                scanf("%s", numToFind);
                Search_num(head, numToFind);
                break;
            }

            case 8:{
                int courseIndex = 0;
                int xz1=0;
                int xz2=0;
                printf("输入你想查找的课程序号:012\n");
                scanf("%d",&xz1);
                printf("最高分0还是最低分1呢?\n");
                scanf("%d",&xz2);
                if(xz2==0) {
                    HLink maxStudent = findMaxScoreStudent(head, xz1);
                    if (maxStudent != NULL) {
                        printf("课程%d 最高分学生信息:\n", xz1 );
                        printf("学号:%s\n", maxStudent->num);
                        printf("姓名:%s\n", maxStudent->name);
                        printf("专业:%s\n", maxStudent->major);
                        printf("班级:%d\n", maxStudent->classNo);
                        printf("成绩:%d\n", maxStudent->score[courseIndex]);
                    } else {
                        printf("未找到最高分学生。\n");
                    }
                }
                //printStudentList(head);
                // 查找并输出最低分学生信息
                if(xz2==1) {
                    HLink minStudent = findMinScoreStudent(head, xz1);
                    if (minStudent != NULL) {
                        printf("课程%d 最低分学生信息:\n", xz1);
                        printf("学号:%s\n", minStudent->num);
                        printf("姓名:%s\n", minStudent->name);
                        printf("专业:%s\n", minStudent->major);
                        printf("班级:%d\n", minStudent->classNo);
                        printf("成绩:%d\n", minStudent->score[courseIndex]);
                    } else {
                        printf("未找到最低分学生。\n");
                    }
                }
                break;
            }
            case 9:{
                int ai=0;
                printf("你要查找平均分最高0还是最低1的学生?\n");
                scanf("%d",&ai);
                if(ai==0) {
                    HLink maxStudent = findMaxAverageStudent(head);
                    if (maxStudent != NULL) {
                        printf("平均分最高的学生信息:\n");
                        printf("学号:%s\n", maxStudent->num);
                        printf("姓名:%s\n", maxStudent->name);
                        printf("专业:%s\n", maxStudent->major);
                        printf("班级:%d\n", maxStudent->classNo);
                        // 计算平均分并输出
                        float average = (maxStudent->score[0] + maxStudent->score[1] + maxStudent->score[2]) / 3.0;
                        printf("平均分:%.2f\n", average);
                    } else {
                        printf("未找到平均分最高的学生。\n");
                    }
                }
                if(ai==1) {
                    // 查找并输出平均分最低的学生信息
                    HLink minStudent = findMinAverageStudent(head);
                    if (minStudent != NULL) {
                        printf("平均分最低的学生信息:\n");
                        printf("学号:%s\n", minStudent->num);
                        printf("姓名:%s\n", minStudent->name);
                        printf("专业:%s\n", minStudent->major);
                        printf("班级:%d\n", minStudent->classNo);
                        // 计算平均分并输出
                        float average = (minStudent->score[0] + minStudent->score[1] + minStudent->score[2]) / 3.0;
                        printf("平均分:%.2f\n", average);
                    } else {
                        printf("未找到平均分最低的学生。\n");
                    }
                }
                break;
            }
            case 10:{
                // 打印未排序的链表
                int g,j;
                printf("选择你要排序的课程012:\n");
                scanf("%d",&g);
                printf("升序0还是降序1?:\n");
                scanf("%d",&j);
                printf("未排序的链表:\n");
                printList1(head);
                if(j==0){
                    // 按第0门课的成绩排序链表
                    sortByCourseScore(head, g);
                }
                if(j==1){
                    // 按第0门课的成绩排序链表
                    sortByCourseScoreDescending(head, g);
                }
                // 按第0门课的成绩排序链表
                //sortByCourseScore(head, 0);

                // 打印排序后的链表
                printf("\n排序后的链表:\n");
                printList1(head);
                break;
            }
            case 11:{
                int g,j;
                printf("升序0还是降序1?:\n");
                scanf("%d",&j);
                // 打印未排序的链表
                printf("未排序的链表:\n");
                printList2(head);
                if(j==0){
                    // 按平均成绩升序排序链表
                    sortByAverageScoreAscending(head);
                }
                if(j==1){
                    // 按平均成绩降序排序链表
                    sortByAverageScoreDescending(head);
                }

                // 打印排序后的链表
                printf("\n按平均成绩升序排序后的链表:\n");
                printList2(head);
                break;
            }
            case 12:{
                int g,j;
                char xiu[20];
                printf("输入你要修改成绩的学生学号:\n");
                scanf("%s",xiu);
                printf("修改第几门课程成绩012?:\n");
                scanf("%d",&j);
                printf("修改为多少分?:\n");
                scanf("%d",&g);
                // 修改学号为 "2023001" 的学生的第一门课程成绩为 90
                modifyScore(head, xiu, j, g);
                printList1(head);
                break;
            }

            case 13:{
                char ace[15];
                char acb[15];
                char acd[15];
                int ha,hu,hi,he;
                // 插入一个新的学生信息并保持链表有序
                printf("请输入学号:\n");
                scanf("%s", ace);
                while (strcmp(ace, "2220221234") == 0 || strcmp(ace, "2220221235") == 0 ||
                strcmp(ace, "2220221236") == 0 || strcmp(ace, "2220221237") == 0 || strcmp(ace, "2220221237") == 0
                || strcmp(ace, "2220221238") == 0|| strcmp(ace, "2220221239") == 0|| strcmp(ace, "2220221240") == 0
                || strcmp(ace, "2220221241") == 0 || strcmp(ace, "2220221242") == 0|| strcmp(ace, "2220221243") == 0){
                    printf("学生已存在,请重新输入学号:\n");
                    scanf("%s", ace);
                }
                printf("请输入姓名:\n");
                scanf("%s", acb);
                printf("请输入专业:\n");
                scanf("%s", acd);
                printf("请输入班级:\n");
                scanf("%d", &ha);
                printf("请输入成绩012::\n");
                scanf("%d %d %d", &hu,&hi,&he);
                InsertList(head, ace, acb, acd, ha, hu, hi, he);
                printStudentList(head);
                break;
            }

            case 14:{
                char numToDelete[15];
                printf("\n请输入要删除的学号:");
                scanf("%s", numToDelete);
                Delete_num(head, numToDelete);
                printStudentList(head);
                break;
            }


            case 15:{
                char acd[15];
                int hu,hi,ha;
                printf("请输入专业:\n");
                scanf("%s", acd);
                printf("第几门成绩012:\n");
                scanf("%d", &hu);
                printf("查找低于0高于1多少分的:\n");
                scanf("%d", &ha);
                if(ha==0){
                    printf("低于多少分:\n");
                    scanf("%d", &hi);
                    HLink resultHead = Search_major_subject_score(head, acd, hu, hi);
                    printf("符合条件的学生信息:\n");
                    PrintStudentList(resultHead);
                }
                if(ha==1){
                    printf("高于多少分:\n");
                    scanf("%d", &hi);
                    HLink resultHead = Search_major_subject_score2(head, acd, hu, hi);
                    printf("符合条件的学生信息:\n");
                    PrintStudentList(resultHead);
                }
                //HLink resultHead = Search_major_subject_score(head, acd, hu, hi);
                //printf("符合条件的学生信息:\n");
                //PrintStudentList(resultHead);
                break;
            }

            case 16:{
                char acd[15];
                int hu,hi,ha;
                printf("请输入专业:\n");
                scanf("%s", acd);
                printf("第几门成绩012:\n");
                scanf("%d", &hu);
                printf("低于多少分0删除还是高于多少分1删除:\n");
                scanf("%d", &ha);
                if(ha==0){
                    printf("删掉低于多少分的:\n");
                    scanf("%d", &hi);
                    printf("\n已删除%s专业,第%d门课程成绩小于%d分的学生\n", acd, hu, hi);
                    Delete_major_subject(head, acd, hu, hi);
                    printStudentList(head);
                }
                if(ha==1){
                    printf("删掉高于多少分的:\n");
                    scanf("%d", &hi);
                    printf("\n已删除%s专业,第%d门课程成绩小于%d分的学生\n", acd, hu, hi);
                    Delete_major_subject2(head, acd, hu, hi);
                    printStudentList(head);
                }

                break;
            }

            case 17:{
                r =886;
                printf("欢迎下次使用");
                break;
            }
        }
        if (r == 886)
            break;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值