c入门第二十一篇: 学生成绩管理系统之成绩排序

前言

在学生成绩管理系统中,必然面临着排序的问题。这里我们简单的将之前讲过的冒泡排序应用于我们的学生成绩管理系统中。
冒泡排序是一种简单的排序算法,它重复地遍历要排序的列表,比较相邻的两个项,如果相邻不是预期的顺序时交换它们,最终达到我们目标的顺序。

按照学生成绩高低进行排序

其核心在于排序算法: 将学生的分数进行比较,然后排序。

c 复制代码
void swap(Student *a, Student *b)
{
    Student tmp = *a;
    *a = *b;
    *b = tmp;
}

void bubble_sort_by_score(Student *s, int n)
{
    int i, j;

    for (i = 0; i < n-1; i++) {
        for (j = 0; j < n-i-1; j++) { // 最后 i 个已经排序好了, 遍历未排序的部分
            if (s[j].score < s[j+1].score) {
                // 如果当前元素大于后面的元素,交换它们
                swap(&s[j], &s[j+1]);
            }
        }
    }
}

完整代码如下:

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // for access() function

#define MAX_STUDENTS 100
#define MAX_NAME_LEN 50
#define STUDENT_SYSTEM "student_system"
#define TRUE 1
#define FALSE 0

typedef struct {
    int id; // 学号
    char name[MAX_NAME_LEN]; // 姓名
    float score; // 成绩
} Student;

int student_count = 0; // 学生数量

Student *students; // 学生数组指针
int g_max_student = MAX_STUDENTS;

Student *stu_sys_init(int num)
{
    Student *stu_sys;
    stu_sys = malloc(num * sizeof(Student));
    if (stu_sys == NULL) {
        printf("student system malloc failed!\n");
    }

    return stu_sys;
}

int write_student_info(Student *s)
{
    FILE *fp = fopen(STUDENT_SYSTEM, "a");
    if (fp == NULL) {
        printf("fopen student_system failed!\n");
        return 1;
    }

    fprintf(fp, "%-4d %-10s %-.2f\n", s->id, s->name, s->score);

    fclose(fp);
    return 0;
}

int check_if_student_exsit(int id)
{
    int i;

    for(i = 0; i < student_count; i++) {
        if(students[i].id == id) {
            return 1;
        }
    }

    return 0;
}

void update_student_info(Student s, int need_write)
{
    Student *stu_reinit;
    int old_max_student;
    int i;

    if(student_count >= g_max_student) {
        old_max_student = g_max_student;
        g_max_student = g_max_student << 1;
        stu_reinit = stu_sys_init(g_max_student);
        if (stu_reinit == NULL) {
            printf("Database is full!\n");
            return;
        }
        memcpy(stu_reinit, students, old_max_student * sizeof(Student));
        free(students);
        students = stu_reinit;
    }

    if (!check_if_student_exsit(s.id)) {
        students[student_count++] = s;
        if (need_write) {
            printf("Student added successfully, all student: %d!\n", student_count);
            write_student_info(&s);
        }
    } else {
        printf("student has in db, do nothing!\n");
    }
}

void add_student()
{
    Student s;

    printf("Enter student ID: ");
    scanf("%d", &s.id);
    printf("Enter student name: ");
    scanf("%s", s.name);
    s.score = 0.0; // 初始成绩设置为0

    update_student_info(s, TRUE);
}

void print_title()
{
    printf("%-4s %-10s %-5s\n", "ID", "Name", "Score");
}

void display_all_students()
{
    int i;

    printf("-------- All students info --------\n");
    if (student_count == 0) {
        printf("No students!\n");
    } else {
        print_title();
        for(i = 0; i < student_count; i++) {
            printf("%-4d %-10s %-.2f\n", students[i].id, students[i].name, students[i].score);
        }
    }
    printf("--------      End       -----------\n");
}

void find_student_by_id()
{
    int id, i;

    printf("Enter student ID to search: ");
    scanf("%d", &id);

    for(i = 0; i < student_count; i++) {
        if(students[i].id == id) {
            print_title();
            printf("%-4d %-10s %-.2f\n", students[i].id, students[i].name, students[i].score);
            return;
        }
    }

    printf("Student with ID %d not found!\n", id);
}

void find_student_by_name()
{
    int i, is_find = 0;
    char name[MAX_NAME_LEN];

    printf("Enter student name to search: ");
    scanf("%s", name);

    for(i = 0; i < student_count; i++) {
        if(strcmp(students[i].name, name) == 0) {
            print_title();
            printf("%-4d %-10s %-.2f\n", students[i].id, students[i].name, students[i].score);
            is_find = 1;
        }
    }

    if (is_find == 0) {
        printf("Student with name %s not found!\n", name);
    }
}

void add_score()
{
    int id, i;
    float score;

    printf("Enter student ID: ");
    scanf("%d", &id);
    printf("Enter student score: ");
    scanf("%f", &score);

    for(i = 0; i < student_count; i++) {
        if(students[i].id == id) {
            students[i].score = score;
            printf("Score added successfully!\n");
            return;
        }
    }
    printf("Student with ID %d not found!\n", id);
}

void display_average_score()
{
    float total = 0.0;
    int i;

    for(i = 0; i < student_count; i++) {
        total += students[i].score;
    }

    printf("Average score of all students: %.2f\n", total / student_count);
}

int init_student_info()
{
    if(access(STUDENT_SYSTEM, F_OK) != 0) { // 文件不存在
        return 0;
    }

    FILE *fp = fopen(STUDENT_SYSTEM, "r");
    if (fp == NULL) {
        printf("fopen student_system failed!\n");
        return 1;
    }

#define BUF_SIZE 1024
    char buf[BUF_SIZE];
    int i = 0;
    Student s;
    while(fgets(buf, BUF_SIZE - 1, fp) != NULL) {
        sscanf(buf, "%d %s %f\n", &s.id, s.name, &s.score);
        update_student_info(s, FALSE);
    }

    fclose(fp);
    return 0;

}

void swap(Student *a, Student *b)
{
    Student tmp = *a;
    *a = *b;
    *b = tmp;
}

void bubble_sort_by_score(Student *s, int n)
{
    int i, j;

    for (i = 0; i < n-1; i++) {
        for (j = 0; j < n-i-1; j++) { // 最后 i 个已经排序好了, 遍历未排序的部分
            if (s[j].score < s[j+1].score) {
                // 如果当前元素大于后面的元素,交换它们
                swap(&s[j], &s[j+1]);
            }
        }
    }
}

int main()
{
    int choice;
    int ret;

    students = stu_sys_init(MAX_STUDENTS);
    if (students == NULL) {
        printf("student system init failed, exit!\n");
        return -1;
    }

    ret = init_student_info();
    if (ret) {
        printf("init_student_info failed!\n");
        return 1;
    }
    display_all_students();

    do {
        printf("\nStudent Score Management System\n");
        printf("0. Exit\n");
        printf("1. Add Student\n");
        printf("2. Display All Students\n");
        printf("3. Find Student by ID\n");
        printf("4. Find Student by Name\n");
        printf("5. Add Score\n");
        printf("6. Display Average Score\n");
        printf("7. Display by Score sort\n");
        printf("Enter your choice: ");
        scanf("%d", &choice);

        switch(choice) {
            case 0:
                printf("Exiting...\n");
                break;
            case 1:
                add_student();
                break;
            case 2:
                display_all_students();
                break;
            case 3:
                find_student_by_id();
                break;
            case 4:
                find_student_by_name();
                break;
            case 5:
                add_score();
                break;
            case 6:
                display_average_score();
                break;
            case 7:
                bubble_sort_by_score(students, student_count);
                display_all_students();
                break;

            default:
                printf("Invalid choice!\n");
        }
    } while(choice != 0);

    return 0;
}
相关推荐
June`13 分钟前
专题三:穷举vs暴搜vs深搜vs回溯vs剪枝(全排列)决策树与递归实现详解
c++·算法·深度优先·剪枝
vlln19 分钟前
适应性神经树:当深度学习遇上决策树的“生长法则”
人工智能·深度学习·算法·决策树·机器学习
我叫珂蛋儿吖35 分钟前
[redis进阶六]详解redis作为缓存&&分布式锁
运维·c语言·数据库·c++·redis·分布式·缓存
来自星星的坤40 分钟前
深入理解 NumPy:Python 科学计算的基石
开发语言·python·numpy
小声读源码1 小时前
【技巧】使用UV创建python项目的开发环境
开发语言·python·uv·dify
yxc_inspire1 小时前
基于Qt的app开发第七天
开发语言·c++·qt·app
zm-v-159304339861 小时前
解锁遥感数据密码:DeepSeek、Python 与 OpenCV 的协同之力
开发语言·python·opencv
冲帕Chompa1 小时前
图论part09dijkstra算法
算法·图论
·云扬·1 小时前
【PmHub后端篇】PmHub中基于Redis加Lua脚本的计数器算法限流实现
redis·算法·lua
周Echo周1 小时前
20、map和set、unordered_map、un_ordered_set的复现
c语言·开发语言·数据结构·c++·算法·leetcode·list