简单的C语言学生成绩管理系统

#include 
#include 
#include 
#include 
#include 

#define MAX_STUDENTS 1000
#define MAX_NAME_LEN 50
#define MAX_ID_LEN 20
#define MAX_SUBJECTS 10
#define FILE_NAME "student_data.dat"

// 定义学生结构体
typedef struct {
    char id[MAX_ID_LEN];          // 学号
    char name[MAX_NAME_LEN];      // 姓名
    char gender;                  // 性别 ('M'/'F')
    int age;                      // 年龄
    char className[MAX_NAME_LEN]; // 班级 (改名为 className)
    float scores[MAX_SUBJECTS];   // 各科成绩
    float average;                // 平均分
    float total;                  // 总分
    int rank;                     // 排名
} Student;

// 定义全局变量
Student students[MAX_STUDENTS];    // 学生数组
int studentCount = 0;             // 当前学生数量
char subjectNames[MAX_SUBJECTS][MAX_NAME_LEN] = {"语文", "数学", "英语", "物理", "化学"}; // 科目名称
int subjectCount = 5;             // 科目数量

// 函数声明
void showMenu();
void addStudent();
void deleteStudent();
void modifyStudent();
void queryStudent();
void inputScores();
void calculateStatistics();
void sortStudents();
void displayAllStudents();
void saveToFile();
void loadFromFile();
void generateReport();
void displayHistogram();
int validateInput(char* str, int type);
void clearInputBuffer();
float calculateAverage(float* scores);
void swap(Student* a, Student* b);
void quickSort(Student* arr, int low, int high);
int partition(Student* arr, int low, int high);
void displayHeader();
void displayStudent(Student* student);
void searchByName();
void searchById();
void modifyScores();
void modifyInfo();
void generateClassReport();
void generateSubjectReport();
void backupData();
void restoreData();
void exportToCsv();

// 主函数
int main() {
    int choice;
    loadFromFile(); // 启动时加载数据

    while (1) {
        showMenu();
        printf("\n请输入您的选择 (1-12): ");
        if (scanf("%d", &choice) != 1) {
            printf("输入无效,请重试!\n");
            clearInputBuffer();
            continue;
        }
        clearInputBuffer();

        switch (choice) {
            case 1:
                addStudent();
                break;
            case 2:
                deleteStudent();
                break;
            case 3:
                modifyStudent();
                break;
            case 4:
                queryStudent();
                break;
            case 5:
                inputScores();
                break;
            case 6:
                calculateStatistics();
                break;
            case 7:
                sortStudents();
                break;
            case 8:
                displayAllStudents();
                break;
            case 9:
                generateReport();
                break;
            case 10:
                saveToFile();
                break;
            case 11:
                displayHistogram();
                break;
            case 12:
                saveToFile();
                printf("\n感谢使用学生成绩管理系统!再见!\n");
                return 0;
            default:
                printf("\n无效的选择,请重试!\n");
        }
    }
}

// 显示主菜单
void showMenu() {
    printf("\n=== 学生成绩管理系统 ===\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("10. 保存数据\n");
    printf("11. 成绩分布图\n");
    printf("12. 退出系统\n");
}

// 添加学生信息
void addStudent() {
    if (studentCount >= MAX_STUDENTS) {
        printf("\n错误:学生数量已达到最大限制!\n");
        return;
    }

    Student newStudent;
    printf("\n=== 添加新学生 ===\n");

    // 输入学号
    do {
        printf("请输入学号: ");
        scanf("%s", newStudent.id);
        clearInputBuffer();
        
        // 检查学号是否已存在
        for (int i = 0; i < studentCount; i++) {
            if (strcmp(students[i].id, newStudent.id) == 0) {
                printf("错误:该学号已存在!\n");
                return;
            }
        }
    } while (!validateInput(newStudent.id, 1));

    // 输入姓名
    do {
        printf("请输入姓名: ");
        scanf("%s", newStudent.name);
        clearInputBuffer();
    } while (!validateInput(newStudent.name, 2));

    // 输入性别
    do {
        printf("请输入性别 (M/F): ");
        scanf("%c", &newStudent.gender);
        clearInputBuffer();
        newStudent.gender = toupper(newStudent.gender);
    } while (newStudent.gender != 'M' && newStudent.gender != 'F');

    // 输入年龄
    do {
        printf("请输入年龄 (15-30): ");
        scanf("%d", &newStudent.age);
        clearInputBuffer();
    } while (newStudent.age < 15 || newStudent.age > 30);

    // 输入班级
    printf("请输入班级: ");
    scanf("%s", newStudent.className);
    clearInputBuffer();

    // 初始化成绩
    for (int i = 0; i < subjectCount; i++) {
        newStudent.scores[i] = -1;  // -1 表示未录入
    }
    newStudent.average = 0;
    newStudent.total = 0;
    newStudent.rank = 0;

    // 添加到数组
    students[studentCount++] = newStudent;
    printf("\n学生信息添加成功!\n");
    saveToFile();  // 自动保存
}

// 删除学生信息
void deleteStudent() {
    char id[MAX_ID_LEN];
    int found = 0;

    printf("\n=== 删除学生信息 ===\n");
    printf("请输入要删除的学生学号: ");
    scanf("%s", id);
    clearInputBuffer();

    for (int i = 0; i < studentCount; i++) {
        if (strcmp(students[i].id, id) == 0) {
            // 显示学生信息确认
            printf("\n找到学生信息:\n");
            displayHeader();
            displayStudent(&students[i]);

            char confirm;
            printf("\n确认删除该学生信息?(Y/N): ");
            scanf("%c", &confirm);
            clearInputBuffer();

            if (toupper(confirm) == 'Y') {
                // 移动后面的元素
                for (int j = i; j < studentCount - 1; j++) {
                    students[j] = students[j + 1];
                }
                studentCount--;
                printf("\n学生信息删除成功!\n");
                saveToFile();  // 自动保存
            } else {
                printf("\n取消删除操作。\n");
            }
            found = 1;
            break;
        }
    }

    if (!found) {
        printf("\n错误:未找到该学号的学生!\n");
    }
}

// 修改学生信息
void modifyStudent() {
    printf("\n=== 修改学生信息 ===\n");
    printf("1. 修改基本信息\n");
    printf("2. 修改成绩信息\n");
    printf("请选择修改类型 (1-2): ");

    int choice;
    scanf("%d", &choice);
    clearInputBuffer();

    switch (choice) {
        case 1:
            modifyInfo();
            break;
        case 2:
            modifyScores();
            break;
        default:
            printf("\n无效的选择!\n");
    }
}

// 修改基本信息
void modifyInfo() {
    char id[MAX_ID_LEN];
    int found = 0;

    printf("\n请输入要修改的学生学号: ");
    scanf("%s", id);
    clearInputBuffer();

    for (int i = 0; i < studentCount; i++) {
        if (strcmp(students[i].id, id) == 0) {
            printf("\n当前学生信息:\n");
            displayHeader();
            displayStudent(&students[i]);

            // 修改信息
            printf("\n请输入新的信息(直接回车保持不变):\n");

            // 修改姓名
            printf("姓名 [%s]: ", students[i].name);
            char input[MAX_NAME_LEN];
            fgets(input, MAX_NAME_LEN, stdin);
            input[strcspn(input, "\n")] = 0;
            if (strlen(input) > 0) {
                strcpy(students[i].name, input);
            }

            // 修改性别
            printf("性别 (M/F) [%c]: ", students[i].gender);
            char gender;
            scanf("%c", &gender);
            clearInputBuffer();
            if (toupper(gender) == 'M' || toupper(gender) == 'F') {
                students[i].gender = toupper(gender);
            }

            // 修改年龄
            printf("年龄 [%d]: ", students[i].age);
            int age;
            if (scanf("%d", &age) == 1) {
                if (age >= 15 && age <= 30) {
                    students[i].age = age;
                }
            }
            clearInputBuffer();

            // 修改班级
            printf("班级 [%s]: ", students[i].className);
            fgets(input, MAX_NAME_LEN, stdin);
            input[strcspn(input, "\n")] = 0;
            if (strlen(input) > 0) {
                strcpy(students[i].className, input);
            }

            printf("\n学生信息修改成功!\n");
            saveToFile();  // 自动保存
            found = 1;
            break;
        }
    }

    if (!found) {
        printf("\n错误:未找到该学号的学生!\n");
    }
}

// 修改成绩信息
void modifyScores() {
    char id[MAX_ID_LEN];
    int found = 0;

    printf("\n请输入要修改成绩的学生学号: ");
    scanf("%s", id);
    clearInputBuffer();

    for (int i = 0; i < studentCount; i++) {
        if (strcmp(students[i].id, id) == 0) {
            printf("\n当前学生成绩:\n");
            displayHeader();
            displayStudent(&students[i]);

            printf("\n请输入新的成绩(-1表示保持不变):\n");
            float newScore;
            for (int j = 0; j < subjectCount; j++) {
                printf("%s [%.1f]: ", subjectNames[j], students[i].scores[j]);
                if (scanf("%f", &newScore) == 1) {
                    if (newScore >= 0 && newScore <= 100) {
                        students[i].scores[j] = newScore;
                    }
                }
                clearInputBuffer();
            }

            // 重新计算平均分和总分
            students[i].total = 0;
            int validScores = 0;
            for (int j = 0; j < subjectCount; j++) {
                if (students[i].scores[j] >= 0) {
                    students[i].total += students[i].scores[j];
                    validScores++;
                }
            }
            if (validScores > 0) {
                students[i].average = students[i].total / validScores;
            }

            printf("\n成绩修改成功!\n");
            saveToFile();  // 自动保存
            found = 1;
            break;
        }
    }

    if (!found) {
        printf("\n错误:未找到该学号的学生!\n");
    }
}

// 查询学生信息
void queryStudent() {
    printf("\n=== 查询学生信息 ===\n");
    printf("1. 按姓名查询\n");
    printf("2. 按学号查询\n");
    printf("请选择查询方式 (1-2): ");

    int choice;
    scanf("%d", &choice);
    clearInputBuffer();

    switch (choice) {
        case 1:
            searchByName();
            break;
        case 2:
            searchById();
            break;
        default:
            printf("\n无效的选择!\n");
    }
}

// 按姓名查询
void searchByName() {
    char name[MAX_NAME_LEN];
    int found = 0;

    printf("\n请输入要查询的学生姓名: ");
    scanf("%s", name);
    clearInputBuffer();

    printf("\n查询结果:\n");
    displayHeader();

    for (int i = 0; i < studentCount; i++) {
        if (strstr(students[i].name, name) != NULL) {
            displayStudent(&students[i]);
            found = 1;
        }
    }

    if (!found) {
        printf("\n未找到匹配的学生信息!\n");
    }
}

// 按学号查询
void searchById() {
    char id[MAX_ID_LEN];
    int found = 0;

    printf("\n请输入要查询的学生学号: ");
    scanf("%s", id);
    clearInputBuffer();

    for (int i = 0; i < studentCount; i++) {
        if (strcmp(students[i].id, id) == 0) {
            printf("\n查询结果:\n");
            displayHeader();
            displayStudent(&students[i]);
            found = 1;
            break;
        }
    }

    if (!found) {
        printf("\n未找到该学号的学生!\n");
    }
}

// 录入成绩
void inputScores() {
    char id[MAX_ID_LEN];
    int found = 0;

    printf("\n=== 录入学生成绩 ===\n");
    printf("请输入要录入成绩的学生学号: ");
    scanf("%s", id);
    clearInputBuffer();

    for (int i = 0; i < studentCount; i++) {
        if (strcmp(students[i].id, id) == 0) {
            printf("\n当前学生信息:\n");
            displayHeader();
            displayStudent(&students[i]);

            printf("\n请输入各科成绩(0-100):\n");
            students[i].total = 0;
            for (int j = 0; j < subjectCount; j++) {
                do {
                    printf("%s: ", subjectNames[j]);
                    scanf("%f", &students[i].scores[j]);
                    clearInputBuffer();
                    if (students[i].scores[j] < 0 || students[i].scores[j] > 100) {
                        printf("成绩必须??0-100之间,请重新输入!\n");
                    }
                } while (students[i].scores[j] < 0 || students[i].scores[j] > 100);
                students[i].total += students[i].scores[j];
            }
            students[i].average = students[i].total / subjectCount;

            printf("\n成绩录入成功!\n");
            saveToFile();  // 自动保存
            found = 1;
            break;
        }
    }

    if (!found) {
        printf("\n错误:未找到该学号的学生!\n");
    }
}

// 统计分析成绩
void calculateStatistics() {
    printf("\n=== 成绩统计分析 ===\n");
    
    // 各科统计数据
    for (int i = 0; i < subjectCount; i++) {
        float max = -1, min = 101, sum = 0, avg;
        int count = 0;
        int distribution[5] = {0}; // 90-100, 80-89, 70-79, 60-69, <60

        for (int j = 0; j < studentCount; j++) {
            if (students[j].scores[i] >= 0) {
                if (students[j].scores[i] > max) max = students[j].scores[i];
                if (students[j].scores[i] < min) min = students[j].scores[i];
                sum += students[j].scores[i];
                count++;

                // 统计分数段
                if (students[j].scores[i] >= 90) distribution[0]++;
                else if (students[j].scores[i] >= 80) distribution[1]++;
                else if (students[j].scores[i] >= 70) distribution[2]++;
                else if (students[j].scores[i] >= 60) distribution[3]++;
                else distribution[4]++;
            }
        }

        if (count > 0) {
            avg = sum / count;
            printf("\n%s成绩统计:\n", subjectNames[i]);
            printf("最高分:%.1f\n", max);
            printf("最低分:%.1f\n", min);
            printf("平均分:%.1f\n", avg);
            printf("成绩分布:\n");
            printf("90-100分:%d人 (%.1f%%)\n", distribution[0], (float)distribution[0]/count*100);
            printf("80-89分:%d人 (%.1f%%)\n", distribution[1], (float)distribution[1]/count*100);
            printf("70-79分:%d人 (%.1f%%)\n", distribution[2], (float)distribution[2]/count*100);
            printf("60-69分:%d人 (%.1f%%)\n", distribution[3], (float)distribution[3]/count*100);
            printf("60分以下:%d人 (%.1f%%)\n", distribution[4], (float)distribution[4]/count*100);
        } else {
            printf("\n%s:暂无成绩数据\n", subjectNames[i]);
        }
    }

    // 总分和平均分统计
    float maxTotal = -1, minTotal = 999999, sumTotal = 0;
    float maxAvg = -1, minAvg = 999999, sumAvg = 0;
    int validCount = 0;

    for (int i = 0; i < studentCount; i++) {
        if (students[i].total > 0) {
            if (students[i].total > maxTotal) maxTotal = students[i].total;
            if (students[i].total < minTotal) minTotal = students[i].total;
            sumTotal += students[i].total;

            if (students[i].average > maxAvg) maxAvg = students[i].average;
            if (students[i].average < minAvg) minAvg = students[i].average;
            sumAvg += students[i].average;

            validCount++;
        }
    }

    if (validCount > 0) {
        printf("\n总分统计:\n");
        printf("最高总分:%.1f\n", maxTotal);
        printf("最低总分:%.1f\n", minTotal);
        printf("平均总分:%.1f\n", sumTotal/validCount);

        printf("\n平均分统计:\n");
        printf("最高平均分:%.1f\n", maxAvg);
        printf("最低平均分:%.1f\n", minAvg);
        printf("总平均分:%.1f\n", sumAvg/validCount);
    } else {
        printf("\n暂无有效的成绩数据!\n");
    }
}

// 成绩排序
void sortStudents() {
    if (studentCount == 0) {
        printf("\n没有学生数据可供排序!\n");
        return;
    }

    printf("\n=== 成绩排序 ===\n");
    printf("1. 按总分排序\n");
    printf("2. 按平均分排序\n");
    printf("3. 按单科成绩排序\n");
    printf("请选择排序方式 (1-3): ");

    int choice;
    scanf("%d", &choice);
    clearInputBuffer();

    if (choice == 3) {
        printf("\n请选择科目:\n");
        for (int i = 0; i < subjectCount; i++) {
            printf("%d. %s\n", i + 1, subjectNames[i]);
        }
        printf("请输入科目编号 (1-%d): ", subjectCount);
        int subject;
        scanf("%d", &subject);
        clearInputBuffer();
        if (subject < 1 || subject > subjectCount) {
            printf("\n无效的科目选择!\n");
            return;
        }
        subject--; // 转换为数组索引

        // 使用快速排序按指定科目成绩排序
        quickSort(students, 0, studentCount - 1);
        
        // 更新排名
        for (int i = 0; i < studentCount; i++) {
            students[i].rank = i + 1;
        }

        printf("\n按%s成绩排序结果:\n", subjectNames[subject]);
        displayHeader();
        for (int i = 0; i < studentCount; i++) {
            displayStudent(&students[i]);
        }
    } else if (choice == 1 || choice == 2) {
        // 使用快速排序按总分或平均分排序
        quickSort(students, 0, studentCount - 1);
        
        // 更新排名
        for (int i = 0; i < studentCount; i++) {
            students[i].rank = i + 1;
        }

        printf("\n排序结果:\n");
        displayHeader();
        for (int i = 0; i < studentCount; i++) {
            displayStudent(&students[i]);
        }
    } else {
        printf("\n无效的选择!\n");
    }
}

// 显示所有学生信息
void displayAllStudents() {
    if (studentCount == 0) {
        printf("\n当前没有学生数据!\n");
        return;
    }

    printf("\n=== 所有学生信息 ===\n");
    displayHeader();
    for (int i = 0; i < studentCount; i++) {
        displayStudent(&students[i]);
    }
    printf("\n共有 %d 名学生\n", studentCount);
}

// 生成成绩报告
void generateReport() {
    printf("\n=== 生成成绩报告 ===\n");
    printf("1. 生成班级成绩报告\n");
    printf("2. 生成学科成绩报告\n");
    printf("3. 导出成绩到CSV文件\n");
    printf("请选择报告类型 (1-3): ");

    int choice;
    scanf("%d", &choice);
    clearInputBuffer();

    switch (choice) {
        case 1:
            generateClassReport();
            break;
        case 2:
            generateSubjectReport();
            break;
        case 3:
            exportToCsv();
            break;
        default:
            printf("\n无效的选择!\n");
    }
}

// 生成班级成绩报告
void generateClassReport() {
    char className[MAX_NAME_LEN];
    int found = 0;

    printf("\n请输入要生成报告的班级: ");
    scanf("%s", className);
    clearInputBuffer();

    // 创建报告文件
    char filename[100];
    sprintf(filename, "%s班级成绩报告.txt", className);
    FILE *fp = fopen(filename, "w");
    if (fp == NULL) {
        printf("\n无法创建报告文件!\n");
        return;
    }

    // 写入报告头部
    fprintf(fp, "=== %s班级成绩报告 ===\n", className);
    time_t now = time(NULL);
    fprintf(fp, "生成时间:%s", ctime(&now));

    // 统计数据
    int classCount = 0;
    float classTotalScore = 0;
    float subjectTotals[MAX_SUBJECTS] = {0};
    int subjectCounts[MAX_SUBJECTS] = {0};

    // 收集数据
    for (int i = 0; i < studentCount; i++) {
        if (strcmp(students[i].className, className) == 0) {
            found = 1;
            classCount++;
            classTotalScore += students[i].total;

            for (int j = 0; j < subjectCount; j++) {
                if (students[i].scores[j] >= 0) {
                    subjectTotals[j] += students[i].scores[j];
                    subjectCounts[j]++;
                }
            }
        }
    }

    if (!found) {
        fprintf(fp, "\n未找到该班级的学生信息!\n");
        fclose(fp);
        printf("\n未找到该班级的学生信息!\n");
        return;
    }

    // 写入统计信息
    fprintf(fp, "\n班级人数:%d\n", classCount);
    fprintf(fp, "班级平均总分:%.2f\n\n", classTotalScore / classCount);

    // 各科目统计
    fprintf(fp, "各科目平均分:\n");
    for (int i = 0; i < subjectCount; i++) {
        if (subjectCounts[i] > 0) {
            fprintf(fp, "%s:%.2f\n", subjectNames[i], subjectTotals[i] / subjectCounts[i]);
        }
    }

    // 写入详细学生信息
    fprintf(fp, "\n学生详细信息:\n");
    fprintf(fp, "学号\t姓名\t性别\t");
    for (int i = 0; i < subjectCount; i++) {
        fprintf(fp, "%s\t", subjectNames[i]);
    }
    fprintf(fp, "总分\t平均分\t排名\n");

    for (int i = 0; i < studentCount; i++) {
        if (strcmp(students[i].className, className) == 0) {
            fprintf(fp, "%s\t%s\t%c\t", 
                    students[i].id, 
                    students[i].name, 
                    students[i].gender);
            
            for (int j = 0; j < subjectCount; j++) {
                if (students[i].scores[j] >= 0) {
                    fprintf(fp, "%.1f\t", students[i].scores[j]);
                } else {
                    fprintf(fp, "N/A\t");
                }
            }
            
            fprintf(fp, "%.1f\t%.1f\t%d\n", 
                    students[i].total, 
                    students[i].average, 
                    students[i].rank);
        }
    }

    fclose(fp);
    printf("\n成绩报告已生成:%s\n", filename);
}

// 生成学科成绩报告
void generateSubjectReport() {
    printf("\n请选择要生成报告的科目:\n");
    for (int i = 0; i < subjectCount; i++) {
        printf("%d. %s\n", i + 1, subjectNames[i]);
    }
    
    int choice;
    printf("请输入科目编号 (1-%d): ", subjectCount);
    scanf("%d", &choice);
    clearInputBuffer();

    if (choice < 1 || choice > subjectCount) {
        printf("\n无效的科目选择!\n");
        return;
    }

    int subjectIndex = choice - 1;
    char filename[100];
    sprintf(filename, "%s成绩报告.txt", subjectNames[subjectIndex]);
    FILE *fp = fopen(filename, "w");
    if (fp == NULL) {
        printf("\n无法创建报告文件!\n");
        return;
    }

    // 写入报告头部
    fprintf(fp, "=== %s成绩报告 ===\n", subjectNames[subjectIndex]);
    time_t now = time(NULL);
    fprintf(fp, "生成时间:%s", ctime(&now));

    // 统计数据
    float max = -1, min = 101, sum = 0;
    int count = 0;
    int distribution[5] = {0}; // 90-100, 80-89, 70-79, 60-69, <60

    // 统计分数分布
    for (int i = 0; i < studentCount; i++) {
        if (students[i].scores[subjectIndex] >= 0) {
            float score = students[i].scores[subjectIndex];
            if (score > max) max = score;
            if (score < min) min = score;
            sum += score;
            count++;

            if (score >= 90) distribution[0]++;
            else if (score >= 80) distribution[1]++;
            else if (score >= 70) distribution[2]++;
            else if (score >= 60) distribution[3]++;
            else distribution[4]++;
        }
    }

    if (count == 0) {
        fprintf(fp, "\n暂无成绩数据!\n");
        fclose(fp);
        printf("\n暂无成绩数据!\n");
        return;
    }

    // 写入统计信息
    fprintf(fp, "\n成绩统计:\n");
    fprintf(fp, "最高分:%.1f\n", max);
    fprintf(fp, "最低分:%.1f\n", min);
    fprintf(fp, "平均分:%.1f\n", sum/count);
    fprintf(fp, "\n成绩分布:\n");
    fprintf(fp, "90-100分:%d人 (%.1f%%)\n", distribution[0], (float)distribution[0]/count*100);
    fprintf(fp, "80-89分:%d人 (%.1f%%)\n", distribution[1], (float)distribution[1]/count*100);
    fprintf(fp, "70-79分:%d人 (%.1f%%)\n", distribution[2], (float)distribution[2]/count*100);
    fprintf(fp, "60-69分:%d人 (%.1f%%)\n", distribution[3], (float)distribution[3]/count*100);
    fprintf(fp, "60分以下:%d人 (%.1f%%)\n", distribution[4], (float)distribution[4]/count*100);

    // 写入详细成绩
    fprintf(fp, "\n详细成绩:\n");
    fprintf(fp, "学号\t姓名\t班级\t成绩\n");
    for (int i = 0; i < studentCount; i++) {
        if (students[i].scores[subjectIndex] >= 0) {
            fprintf(fp, "%s\t%s\t%s\t%.1f\n",
                    students[i].id,
                    students[i].name,
                    students[i].className,
                    students[i].scores[subjectIndex]);
        }
    }

    fclose(fp);
    printf("\n成绩报告已生成:%s\n", filename);
}

// 导出成绩到CSV文件
void exportToCsv() {
    char filename[100];
    printf("\n请输入导出文件名(如 scores.csv): ");
    scanf("%s", filename);
    clearInputBuffer();

    FILE *fp = fopen(filename, "w");
    if (fp == NULL) {
        printf("\n无法创建文件!\n");
        return;
    }

    // 写入表头
    fprintf(fp, "学号,姓名,性别,年龄,班级,");
    for (int i = 0; i < subjectCount; i++) {
        fprintf(fp, "%s,", subjectNames[i]);
    }
    fprintf(fp, "总分,平均分,排名\n");

    // 写入学生数据
    for (int i = 0; i < studentCount; i++) {
        fprintf(fp, "%s,%s,%c,%d,%s,",
                students[i].id,
                students[i].name,
                students[i].gender,
                students[i].age,
                students[i].className);

        for (int j = 0; j < subjectCount; j++) {
            if (students[i].scores[j] >= 0) {
                fprintf(fp, "%.1f,", students[i].scores[j]);
            } else {
                fprintf(fp, "N/A,");
            }
        }

        fprintf(fp, "%.1f,%.1f,%d\n",
                students[i].total,
                students[i].average,
                students[i].rank);
    }

    fclose(fp);
    printf("\n数据已成功导出到:%s\n", filename);
}

// 显示成绩分布直方图
void displayHistogram() {
    if (studentCount == 0) {
        printf("\n暂无学生数据!\n");
        return;
    }

    printf("\n=== 成绩分布直方图 ===\n");
    printf("请选择要显示的科目:\n");
    for (int i = 0; i < subjectCount; i++) {
        printf("%d. %s\n", i + 1, subjectNames[i]);
    }
    printf("%d. 总分\n", subjectCount + 1);
    printf("%d. 平均分\n", subjectCount + 2);

    int choice;
    printf("请输入选择 (1-%d): ", subjectCount + 2);
    scanf("%d", &choice);
    clearInputBuffer();

    if (choice < 1 || choice > subjectCount + 2) {
        printf("\n无效的选择!\n");
        return;
    }

    int distribution[5] = {0}; // 90-100, 80-89, 70-79, 60-69, <60
    int validCount = 0;
    float maxValue = 0;

    // 统计分布
    if (choice <= subjectCount) {
        // 单科成绩分布
        int subject = choice - 1;
        for (int i = 0; i < studentCount; i++) {
            if (students[i].scores[subject] >= 0) {
                float score = students[i].scores[subject];
                if (score >= 90) distribution[0]++;
                else if (score >= 80) distribution[1]++;
                else if (score >= 70) distribution[2]++;
                else if (score >= 60) distribution[3]++;
                else distribution[4]++;
                validCount++;
            }
        }
        printf("\n%s成绩分布:\n", subjectNames[subject]);
    } else if (choice == subjectCount + 1) {
        // 总分分布
        for (int i = 0; i < studentCount; i++) {
            if (students[i].total > 0) {
                float score = students[i].total / (subjectCount * 100) * 100;
                if (score >= 90) distribution[0]++;
                else if (score >= 80) distribution[1]++;
                else if (score >= 70) distribution[2]++;
                else if (score >= 60) distribution[3]++;
                else distribution[4]++;
                validCount++;
            }
        }
        printf("\n总分分布:\n");
    } else {
        // 平均分分布
        for (int i = 0; i < studentCount; i++) {
            if (students[i].average > 0) {
                if (students[i].average >= 90) distribution[0]++;
                else if (students[i].average >= 80) distribution[1]++;
                else if (students[i].average >= 70) distribution[2]++;
                else if (students[i].average >= 60) distribution[3]++;
                else distribution[4]++;
                validCount++;
            }
        }
        printf("\n平均分分布:\n");
    }

    if (validCount == 0) {
        printf("暂无有效数据!\n");
        return;
    }

    // 找出最大值用于缩放
    for (int i = 0; i < 5; i++) {
        if (distribution[i] > maxValue) {
            maxValue = distribution[i];
        }
    }

    // 显示直方图
    const int MAX_STARS = 50; // 最大显示宽度
    const char* labels[] = {"90-100", "80-89", "70-79", "60-69", "<60"};

    for (int i = 0; i < 5; i++) {
        printf("%-7s |", labels[i]);
        int stars = (int)((distribution[i] / maxValue) * MAX_STARS);
        for (int j = 0; j < stars; j++) {
            printf("*");
        }
        printf(" %d (%.1f%%)\n", distribution[i], (float)distribution[i]/validCount*100);
    }
}

// 保存数据到文件
void saveToFile() {
    FILE *fp = fopen(FILE_NAME, "wb");
    if (fp == NULL) {
        printf("\n无法保存数据!\n");
        return;
    }

    fwrite(&studentCount, sizeof(int), 1, fp);
    fwrite(students, sizeof(Student), studentCount, fp);
    fclose(fp);

    printf("\n数据保存成功!\n");
}

// 从文件加载数据
void loadFromFile() {
    FILE *fp = fopen(FILE_NAME, "rb");
    if (fp == NULL) {
        printf("\n未找到数据文件,将创建新文件。\n");
        return;
    }

    fread(&studentCount, sizeof(int), 1, fp);
    fread(students, sizeof(Student), studentCount, fp);
    fclose(fp);

    printf("\n数据加载成功!\n");
}

// 显示表头
void displayHeader() {
    printf("\n学号\t姓名\t性别\t年龄\t班级\t");
    for (int i = 0; i < subjectCount; i++) {
        printf("%s\t", subjectNames[i]);
    }
    printf("总分\t平均分\t排名\n");
    printf("--------------------------------------------------------------------\n");
}

// 显示单个学生信息
void displayStudent(Student* student) {
    printf("%s\t%s\t%c\t%d\t%s\t",
            student->id,
            student->name,
            student->gender,
            student->age,
            student->className);

    for (int i = 0; i < subjectCount; i++) {
        if (student->scores[i] >= 0) {
            printf("%.1f\t", student->scores[i]);
        } else {
            printf("N/A\t");
        }
    }

    printf("%.1f\t%.1f\t%d\n",
            student->total,
            student->average,
            student->rank);
}

// 验证输入
int validateInput(char* str, int type) {
    if (strlen(str) == 0) return 0;
    
    switch (type) {
        case 1: // 学号
            if (strlen(str) > MAX_ID_LEN - 1) return 0;
            for (int i = 0; str[i]; i++) {
                if (!isalnum(str[i])) return 0;
            }
            break;
        case 2: // 姓名
            if (strlen(str) > MAX_NAME_LEN - 1) return 0;
            break;
    }
    return 1;
}

// 清除输入缓冲区
void clearInputBuffer() {
    int c;
    while ((c = getchar()) != '\n' && c != EOF);
}

// 计算平均分
float calculateAverage(float* scores) 
{
    float sum = 0;
    int count = 0;
    for (int i = 0; i < subjectCount; i++) 
    {
        if (scores[i] >= 0) {
            sum += scores[i];
            count++;
        }
    }
    return count > 0 ? sum / count : 0;
}

// 交换两个学生的位置
void swap(Student* a, Student* b) 
{
    Student temp = *a;
    *a = *b;
    *b = temp;
}

// 快速排序分区
int partition(Student* arr, int low, int high) 
{
    Student pivot = arr[high];
    int i = low - 1;

    for (int j = low; j < high; j++) 
    {
        if (arr[j].total >= pivot.total) 
        {
            i++;
            swap(&arr[i], &arr[j]);
        }
    }
    swap(&arr[i + 1], &arr[high]);
    return i + 1;
}

// 快速排序
void quickSort(Student* arr, int low, int high) 
{
    if (low < high) 
    {
        int pi = partition(arr, low, high);
        quickSort(arr, low, pi - 1);
        quickSort(arr, pi + 1, high);
    }
}

你可能感兴趣的:(c语言,开发语言)