C语言学生成绩管理系统如何设计与实现?

99ANYc3cd6
预计阅读时长 43 分钟
位置: 首页 C语言 正文

系统设计概述

设计目标

  • 功能完备:实现学生信息的增、删、改、查、排序和统计等基本功能。
  • 结构清晰:采用模块化设计,将不同功能封装到不同的函数中,提高代码的可读性和可维护性。
  • 数据持久化:使用文件存储学生数据,确保程序关闭后数据不丢失。
  • 用户友好:提供清晰、简洁的菜单界面,方便用户操作。
  • 健壮性:对用户的非法输入(如输入非数字、超出范围的选择等)进行简单的处理。

功能模块划分

系统可以划分为以下几个核心模块:

学生成绩管理系统设计 c语言
(图片来源网络,侵删)
  1. 主模块:显示主菜单,并根据用户选择调用其他功能模块。
  2. 数据结构模块:定义学生信息的结构体。
  3. 文件操作模块:负责从文件中读取数据(loadData)和将数据保存到文件(saveData)。
  4. 录入模块:添加新的学生信息。
  5. 查询模块:按学号或姓名查询学生信息。
  6. 修改模块:根据学号找到学生并修改其信息。
  7. 删除模块:根据学号删除学生信息。
  8. 显示模块:以表格形式显示所有学生信息。
  9. 排序模块:按总成绩或单科成绩进行排序。
  10. 统计模块:计算并显示班级的平均分、最高分、最低分等。
  11. 退出模块:保存数据并退出程序。

核心数据结构设计

使用 struct 来定义学生信息,并将其封装在一个结构体数组中。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h> // 用于 getch(),实现无回显输入
#include <ctype.h> // 用于字符处理
// 定义最大学生数量
#define MAX_STUDENTS 100
// 定义学生信息结构体
typedef struct {
    char id[20];        // 学号
    char name[50];      // 姓名
    float score_math;   // 数学成绩
    float score_english;// 英语成绩
    float score_c;      // C语言成绩
    float total_score;  // 总成绩
    float average;      // 平均分
} Student;
// 全局变量:学生数组和学生数量
Student students[MAX_STUDENTS];
int student_count = 0;

核心功能函数实现

文件操作

// 从文件加载数据
void loadData() {
    FILE *fp = fopen("students.dat", "rb");
    if (fp == NULL) {
        printf("文件不存在或无法打开,将创建新文件,\n");
        return;
    }
    fread(&student_count, sizeof(int), 1, fp);
    fread(students, sizeof(Student), student_count, fp);
    fclose(fp);
    printf("数据加载成功!共加载 %d 名学生信息,\n", student_count);
}
// 保存数据到文件
void saveData() {
    FILE *fp = fopen("students.dat", "wb");
    if (fp == NULL) {
        printf("错误:无法保存数据到文件!\n");
        return;
    }
    fwrite(&student_count, sizeof(int), 1, fp);
    fwrite(students, sizeof(Student), student_count, fp);
    fclose(fp);
    printf("数据保存成功!\n");
}

录入功能

// 录入学生信息
void addStudent() {
    if (student_count >= MAX_STUDENTS) {
        printf("学生数量已达上限,无法继续添加!\n");
        return;
    }
    Student s;
    printf("请输入学号: ");
    scanf("%s", s.id);
    printf("请输入姓名: ");
    scanf("%s", s.name);
    printf("请输入数学成绩: ");
    scanf("%f", &s.score_math);
    printf("请输入英语成绩: ");
    scanf("%f", &s.score_english);
    printf("请输入C语言成绩: ");
    scanf("%f", &s.score_c);
    s.total_score = s.score_math + s.score_english + s.score_c;
    s.average = s.total_score / 3.0;
    students[student_count++] = s;
    printf("学生信息添加成功!\n");
}

查询功能

// 按学号查询
void searchById() {
    char id[20];
    printf("请输入要查询的学号: ");
    scanf("%s", id);
    for (int i = 0; i < student_count; i++) {
        if (strcmp(students[i].id, id) == 0) {
            printf("\n--- 查询结果 ---\n");
            printf("学号: %s\n", students[i].id);
            printf("姓名: %s\n", students[i].name);
            printf("数学: %.2f\n", students[i].score_math);
            printf("英语: %.2f\n", students[i].score_english);
            printf("C语言: %.2f\n", students[i].score_c);
            printf("总分: %.2f\n", students[i].total_score);
            printf("平均分: %.2f\n", students[i].average);
            printf("----------------\n");
            return;
        }
    }
    printf("未找到学号为 %s 的学生!\n", id);
}
// 按姓名查询
void searchByName() {
    char name[50];
    printf("请输入要查询的姓名: ");
    scanf("%s", name);
    int found = 0;
    for (int i = 0; i < student_count; i++) {
        if (strcmp(students[i].name, name) == 0) {
            found = 1;
            printf("\n--- 查询结果 ---\n");
            printf("学号: %s\n", students[i].id);
            printf("姓名: %s\n", students[i].name);
            printf("数学: %.2f\n", students[i].score_math);
            printf("英语: %.2f\n", students[i].score_english);
            printf("C语言: %.2f\n", students[i].score_c);
            printf("总分: %.2f\n", students[i].total_score);
            printf("平均分: %.2f\n", students[i].average);
            printf("----------------\n");
        }
    }
    if (!found) {
        printf("未找到姓名为 %s 的学生!\n", name);
    }
}

修改功能

void modifyStudent() {
    char id[20];
    printf("请输入要修改的学生学号: ");
    scanf("%s", id);
    for (int i = 0; i < student_count; i++) {
        if (strcmp(students[i].id, id) == 0) {
            printf("找到学生 %s,请输入新信息(直接回车则保留原值):\n", students[i].name);
            char temp[50];
            printf("新姓名 (%s): ", students[i].name);
            getchar(); // 清除输入缓冲区
            fgets(temp, sizeof(temp), stdin);
            if (strlen(temp) > 1) temp[strlen(temp)-1] = '\0'; // 去掉换行符
            if (strlen(temp) > 0) strcpy(students[i].name, temp);
            printf("新数学成绩 (%.2f): ", students[i].score_math);
            fgets(temp, sizeof(temp), stdin);
            if (strlen(temp) > 1 && atof(temp) >= 0) students[i].score_math = atof(temp);
            printf("新英语成绩 (%.2f): ", students[i].score_english);
            fgets(temp, sizeof(temp), stdin);
            if (strlen(temp) > 1 && atof(temp) >= 0) students[i].score_english = atof(temp);
            printf("新C语言成绩 (%.2f): ", students[i].score_c);
            fgets(temp, sizeof(temp), stdin);
            if (strlen(temp) > 1 && atof(temp) >= 0) students[i].score_c = atof(temp);
            students[i].total_score = students[i].score_math + students[i].score_english + students[i].score_c;
            students[i].average = students[i].total_score / 3.0;
            printf("学生信息修改成功!\n");
            return;
        }
    }
    printf("未找到学号为 %s 的学生!\n", id);
}

删除功能

void deleteStudent() {
    char id[20];
    printf("请输入要删除的学生学号: ");
    scanf("%s", id);
    for (int i = 0; i < student_count; i++) {
        if (strcmp(students[i].id, id) == 0) {
            // 将后面的所有学生前移一位
            for (int j = i; j < student_count - 1; j++) {
                students[j] = students[j + 1];
            }
            student_count--;
            printf("学号为 %s 的学生信息已删除!\n", id);
            return;
        }
    }
    printf("未找到学号为 %s 的学生!\n", id);
}

显示功能

void displayAllStudents() {
    if (student_count == 0) {
        printf("当前没有学生信息!\n");
        return;
    }
    printf("\n%-15s %-10s %-10s %-10s %-10s %-10s %-10s\n", 
           "学号", "姓名", "数学", "英语", "C语言", "总分", "平均分");
    printf("-----------------------------------------------------------------\n");
    for (int i = 0; i < student_count; i++) {
        printf("%-15s %-10s %-10.2f %-10.2f %-10.2f %-10.2f %-10.2f\n",
               students[i].id, students[i].name,
               students[i].score_math, students[i].score_english, students[i].score_c,
               students[i].total_score, students[i].average);
    }
}

排序功能 (使用冒泡排序,易于理解)

// 比较函数,用于按总分降序排序
int compareByTotal(const void *a, const void *b) {
    Student *s1 = (Student *)a;
    Student *s2 = (Student *)b;
    if (s2->total_score > s1->total_score) return 1;
    else if (s2->total_score < s1->total_score) return -1;
    else return 0;
}
// 按总分排序
void sortByTotalScore() {
    qsort(students, student_count, sizeof(Student), compareByTotal);
    printf("已按总分从高到低排序!\n");
}

统计功能

void calculateStatistics() {
    if (student_count == 0) {
        printf("当前没有学生信息,无法统计!\n");
        return;
    }
    float sum_math = 0, sum_eng = 0, sum_c = 0;
    float max_math = students[0].score_math, min_math = students[0].score_math;
    float max_eng = students[0].score_english, min_eng = students[0].score_english;
    float max_c = students[0].score_c, min_c = students[0].score_c;
    for (int i = 0; i < student_count; i++) {
        sum_math += students[i].score_math;
        sum_eng += students[i].score_english;
        sum_c += students[i].score_c;
        if (students[i].score_math > max_math) max_math = students[i].score_math;
        if (students[i].score_math < min_math) min_math = students[i].score_math;
        if (students[i].score_english > max_eng) max_eng = students[i].score_english;
        if (students[i].score_english < min_eng) min_eng = students[i].score_english;
        if (students[i].score_c > max_c) max_c = students[i].score_c;
        if (students[i].score_c < min_c) min_c = students[i].score_c;
    }
    printf("\n--- 成绩统计 ---\n");
    printf("科目\t平均分\t最高分\t最低分\n");
    printf("--------------------------------\n");
    printf("数学\t%.2f\t%.2f\t%.2f\n", sum_math / student_count, max_math, min_math);
    printf("英语\t%.2f\t%.2f\t%.2f\n", sum_eng / student_count, max_eng, min_eng);
    printf("C语言\t%.2f\t%.2f\t%.2f\n", sum_c / student_count, max_c, min_c);
    printf("----------------\n");
}

主菜单与程序入口

// 显示主菜单
void showMenu() {
    system("cls"); // Windows下清屏,Linux/macOS用 system("clear");
    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("      0. 退出系统\n");
    printf("=====================================\n");
    printf("请输入您的选择: ");
}
int main() {
    // 程序启动时加载数据
    loadData();
    int choice;
    do {
        showMenu();
        scanf("%d", &choice);
        switch (choice) {
            case 1: addStudent(); break;
            case 2: 
                printf("--- 查询方式 ---\n1.按学号 2.按姓名\n请选择: ");
                int search_choice;
                scanf("%d", &search_choice);
                if(search_choice == 1) searchById();
                else if(search_choice == 2) searchByName();
                else printf("无效选择!\n");
                break;
            case 3: modifyStudent(); break;
            case 4: deleteStudent(); break;
            case 5: displayAllStudents(); break;
            case 6: sortByTotalScore(); break;
            case 7: calculateStatistics(); break;
            case 0: 
                saveData();
                printf("感谢使用,再见!\n");
                break;
            default: printf("无效的选择,请重新输入!\n");
        }
        if (choice != 0) {
            printf("\n按任意键返回主菜单...");
            getch(); // 等待用户按键
        }
    } while (choice != 0);
    return 0;
}

系统扩展与优化建议

  1. 密码登录:增加一个简单的密码验证功能,保护数据安全。
  2. 动态内存分配:使用 mallocrealloc 动态分配内存,而不是使用固定大小的数组,这样可以处理任意数量的学生。
  3. 更健壮的输入验证:对成绩输入进行范围检查(如0-100),防止非法数据。
  4. 多条件排序:允许用户选择按总分、数学、英语或C语言进行排序。
  5. 图形用户界面:如果使用支持图形库的编译器(如 graphics.h 或第三方库),可以开发一个带有窗口和按钮的GUI版本。
  6. 数据加密:对于敏感数据,可以在写入文件前进行简单的加密,读取时解密。
  7. 分页显示:当学生数量很多时,实现分页显示功能,避免屏幕刷得太快。

这个设计方案为你提供了一个坚实的基础,你可以根据这个框架进行编码、测试和进一步的扩展,祝你项目顺利!

学生成绩管理系统设计 c语言
(图片来源网络,侵删)
-- 展开阅读全文 --
头像
dede5.7是否兼容当前PHP版本?
« 上一篇 02-18
如何让织梦点击出现二级栏目?
下一篇 » 02-18

相关文章

取消
微信二维码
支付宝二维码

目录[+]