C语言学生管理系统|结构体数组+文件操作+按照姓名排序

也是第一次使用Markdown语法orz

定义结构体

struct student {
    char name[10];
    char sex[5];
    int age;
    int num;
    int score[5];//需要储存五门课的成绩
};

struct class {
    struct student st[50];//最大可存储50个学生信息
    int n;
};

主菜单函数

    printf("学生管理系统\n");//不解释,只不过这个没有居中显示,不太美观
    printf("\n");
    printf("1.添加学生信息。\n");
    printf("2.显示学生信息。\n");
    printf("3.查询学生信息。\n");
    printf("4.修改学生信息。\n");
    printf("5.删除学生信息。\n");
    printf("6.退出系统。\n");
    printf("\n");
    printf("请输入相应的序号:");
}

添加学生信息

void add(struct class *p) {//参数为一个指针指向结构体数组
    if (p->n >= 50) {
        printf("学生数量已达上限,无法添加更多学生。\n");
        return;
    }

    FILE *fp = fopen("学生管理信息.txt", "a");//a代表追加,说明你要开始写文件了
    if (fp == NULL) {
        perror("文件打开失败");
        return;
    }

    printf("输入学生姓名:\n");
    scanf("%9s", p->st[p->n].name);
    printf("输入学生性别:\n");
    scanf("%4s", p->st[p->n].sex);
    printf("输入学生年龄:\n");
    scanf("%d", &p->st[p->n].age);
    printf("输入学生学号:\n");
    scanf("%d", &p->st[p->n].num);
    printf("输入学生成绩:\n");
    for (int i = 0; i < 5; i++) scanf("%d", &p->st[p->n].score[i]);

    fprintf(fp, "%s %s %d %d ", p->st[p->n].name, p->st[p->n].sex, p->st[p->n].age, p->st[p->n].num);//fprintf将刚刚输入的学生信息写入文件
    for (int i = 0; i < 5; i++) {
        fprintf(fp, "%d ", p->st[p->n].score[i]);
    }
    fprintf(fp, "\n");
    p->n++;//学生人数加一
    fclose(fp);
    printf("学生的信息添加成功。\n");
}

显示学生信息

void view(struct class *p) {
    if (p->n == 0) {
        printf("没有学生信息可供显示。\n");
        return;
    }

    printf("姓名\t性别\t年龄\t学号\t成绩\n");//制表符对齐显示
    for (int i = 0; i < p->n; i++) {
        printf("%s\t%s\t%d\t%d\t", p->st[i].name, p->st[i].sex, p->st[i].age, p->st[i].num);
        for (int j = 0; j < 5; j++) {
            printf("%d ", p->st[i].score[j]);
        }
        printf("\n");
    }
}

查找某学生(按学号查找和按姓名查找)

int search(struct class *p, int mode) {//mode是用户想按哪个查找学生,会在主函数中显示,不要着急
    int i;
    char name[10]; 
    int num;

    if (mode == 1) {
        // 按学号查询
        printf("输入要查找的学生学号: ");
        scanf("%d", &num);
        for (i = 0; i < p->n; i++) {
            if (num == p->st[i].num) {
        
                printf("学生信息:\n");
                printf("姓名: %s\n", p->st[i].name);
                printf("性别: %s\n", p->st[i].sex);
                printf("年龄: %d\n", p->st[i].age); 
                printf("学号: %d\n", p->st[i].num);
                printf("成绩: ");
                for (int j = 0; j < 5; j++) {
                    printf("%d ", p->st[i].score[j]);
                }
                printf("\n");
                return i; 
            }
        }
    } else if (mode == 2) {
        printf("输入要查找的学生姓名: ");
        scanf("%9s", name); 
        for (i = 0; i < p->n; i++) {
            if (strcmp(name, p->st[i].name) == 0) {
                printf("学生信息:\n");
                printf("姓名: %s\n", p->st[i].name);
                printf("性别: %s\n", p->st[i].sex);
                printf("年龄: %d\n", p->st[i].age); 
                printf("学号: %d\n", p->st[i].num);
                printf("成绩: ");
                for (int j = 0; j < 5; j++) {
                    printf("%d ", p->st[i].score[j]);
                }
                printf("\n");
                return i; 
            }
        }
    } else {
        printf("无效的查询模式。\n");
        return -1;
    }

    printf("学生不存在。\n");
    return -1; 
}

按学生姓名排序

void sortByName(struct class *p) {
    for (int i = 0; i < p->n - 1; i++) {//选择法排序
        for (int j = i + 1; j < p->n; j++) {
            if (strcmp(p->st[i].name, p->st[j].name) > 0) {
            
                struct student temp = p->st[i];//定义一个结构体变量临时储存,以便交换
                p->st[i] = p->st[j];
                p->st[j] = temp;
            }
        }
    }
}

修改学生信息

void change(struct class *p) {
    int ret, choose;
    ret = search(p, 1); //在此调用search函数,以便查找需要修改的学生,此时默认按学号进行查找
    if (ret != -1) {
        while (1) {
            printf("修改学生信息中的哪一项?\n");
            printf("1.姓名\n");
            printf("2.性别\n");
            printf("3.年龄\n");
            printf("4.学号\n");
            printf("5.成绩\n");
            scanf("%d", &choose);

            switch (choose) {
                case 1:
                    printf("输入新的学生姓名:\n");
                    scanf("%s", p->st[ret].name);
                    break;
                case 2:
                    printf("输入新的学生性别:\n");
                    scanf("%s", p->st[ret].sex);
                    break;
                case 3:
                    printf("输入新的学生年龄:\n");
                    scanf("%d", &p->st[ret].age);
                    break;
                case 4:
                    printf("输入新的学生学号:\n");
                    scanf("%d", &p->st[ret].num);
                    break;
                case 5:
                    printf("请输入新的学生成绩:\n");
                    for (int i = 0; i < 5; i++) scanf("%d", &p->st[ret].score[i]);
                    break;
                default:
                    printf("输入错误。\n");
                    continue;
            }
            FILE *fp = fopen("学生管理信息.txt", "w");//将修改的信息写入文件,w为只写
            if (fp == NULL) {
                printf("文件打开失败。\n");
                return;
            }

            for (int i = 0; i < p->n; i++) {
                fprintf(fp, "%s %s %d %d ", p->st[i].name, p->st[i].sex, p->st[i].age, p->st[i].num);
                for (int j = 0; j < 5; j++) {  
                    fprintf(fp, "%d ", p->st[i].score[j]);
                }
                fprintf(fp, "\n");
            }
            fclose(fp);
            printf("学生信息已更新。\n");
            break;
        }
    } else {
        printf("没有找到该学生。\n");
    }
}

删除指定学生

int delet(struct class *p) {
    int num, ret;

    printf("输入要删除的学生学号:\n");
    scanf("%d", &num);

    ret = search(p, 1);
    if (ret != -1) {
        for (int i = ret; i < p->n - 1; i++) {
            p->st[i] = p->st[i + 1];//数组整体从删除学生项向前移动
        }
        p->n--;//人数减一要记得

        FILE *fp = fopen("学生管理信息.txt", "w");
        if (fp == NULL) {
            printf("文件打开失败。\n");
            return -1;
        }

        for (int i = 0; i < p->n; i++) {
            fprintf(fp, "%s %s %d %d ", p->st[i].name, p->st[i].sex, p->st[i].age, p->st[i].num);
            for (int j = 0; j < 5; j++) {  
                fprintf(fp, "%d ", p->st[i].score[j]);
            }
            fprintf(fp, "\n");
        }

        fclose(fp);
        printf("学生信息已删除。\n");
        return 0;
    } else {
        printf("没有找到该学号的学生。\n");
        return -1;
    }
}

定义保存文件函数,下次运行程序可以看到上次保存的信息

void load(struct class *p) {
    FILE *fp = fopen("学生管理信息.txt", "r");
    if (fp == NULL) {
        printf("文件打开失败或文件为空。\n");
        return;
    }

    p->n = 0; 
    while (fscanf(fp, "%s %s %d %d %d %d %d %d %d\n", p->st[p->n].name, p->st[p->n].sex, &p->st[p->n].age, &p->st[p->n].num, &p->st[p->n].score[0], &p->st[p->n].score[1], &p->st[p->n].score[2], &p->st[p->n].score[3], &p->st[p->n].score[4]) != EOF) {//得保证写入信息不为空才能保存
        p->n++;
    }

    fclose(fp);
}

主函数

    int choose, searchMode;
    struct class p = {0};
    load(&p);
    while (1) {
        menu();
        scanf("%d", &choose);

        switch (choose) {
            case 1:
                add(&p);
                load(&p);//添加学生之后要保存到文件
                break;
            case 2:
                sortByName(&p);//查看学生之前先进行排序
                view(&p);
                break;
            case 3:
                printf("选择查询方式(1-按学号,2-按姓名):");
                scanf("%d", &searchMode);
                search(&p, searchMode);
                break;
            case 4:
                change(&p);
                load(&p);//修改之后要保存
                break;
            case 5:
                delet(&p);
                load(&p);//删除之后要更新
                break;
            case 6:
                return 0;
            default:
                printf("输入错误,请重新输入。\n");
                break;
        }
    }

    return 0;
}

完整代码

#include <stdio.h>
#include <string.h>

struct student {
    char name[10];
    char sex[5];
    int age;
    int num;
    int score[5];
};

struct class {
    struct student st[50];
    int n;
};

void menu() { //刚刚没有显示的菜单函数
    printf("学生管理系统\n");
    printf("\n");
    printf("1.添加学生信息。\n");
    printf("2.显示学生信息。\n");
    printf("3.查询学生信息。\n");
    printf("4.修改学生信息。\n");
    printf("5.删除学生信息。\n");
    printf("6.退出系统。\n");
    printf("\n");
    printf("请输入相应的序号:");
}

void add(struct class *p) {
    if (p->n >= 50) {
        printf("学生数量已达上限,无法添加更多学生。\n");
        return;
    }

    FILE *fp = fopen("学生管理信息.txt", "a");
    if (fp == NULL) {
        perror("文件打开失败");
        return;
    }

    printf("输入学生姓名:\n");
    scanf("%9s", p->st[p->n].name);
    printf("输入学生性别:\n");
    scanf("%4s", p->st[p->n].sex);
    printf("输入学生年龄:\n");
    scanf("%d", &p->st[p->n].age);
    printf("输入学生学号:\n");
    scanf("%d", &p->st[p->n].num);
    printf("输入学生成绩:\n");
    for (int i = 0; i < 5; i++) scanf("%d", &p->st[p->n].score[i]);

    fprintf(fp, "%s %s %d %d ", p->st[p->n].name, p->st[p->n].sex, p->st[p->n].age, p->st[p->n].num);
    for (int i = 0; i < 5; i++) {
        fprintf(fp, "%d ", p->st[p->n].score[i]);
    }
    fprintf(fp, "\n");
    p->n++;
    fclose(fp);
    printf("学生的信息添加成功。\n");
}

void view(struct class *p) {
    if (p->n == 0) {
        printf("没有学生信息可供显示。\n");
        return;
    }

    printf("姓名\t性别\t年龄\t学号\t成绩\n");
    for (int i = 0; i < p->n; i++) {
        printf("%s\t%s\t%d\t%d\t", p->st[i].name, p->st[i].sex, p->st[i].age, p->st[i].num);
        for (int j = 0; j < 5; j++) {
            printf("%d ", p->st[i].score[j]);
        }
        printf("\n");
    }
}

int search(struct class *p, int mode) {
    int i;
    char name[10]; 
    int num;

    if (mode == 1) {
        // 按学号查询
        printf("输入要查找的学生学号: ");
        scanf("%d", &num);
        for (i = 0; i < p->n; i++) {
            if (num == p->st[i].num) {
        
                printf("学生信息:\n");
                printf("姓名: %s\n", p->st[i].name);
                printf("性别: %s\n", p->st[i].sex);
                printf("年龄: %d\n", p->st[i].age); 
                printf("学号: %d\n", p->st[i].num);
                printf("成绩: ");
                for (int j = 0; j < 5; j++) {
                    printf("%d ", p->st[i].score[j]);
                }
                printf("\n");
                return i; 
            }
        }
    } else if (mode == 2) {
        printf("输入要查找的学生姓名: ");
        scanf("%9s", name); 
        for (i = 0; i < p->n; i++) {
            if (strcmp(name, p->st[i].name) == 0) {
                printf("学生信息:\n");
                printf("姓名: %s\n", p->st[i].name);
                printf("性别: %s\n", p->st[i].sex);
                printf("年龄: %d\n", p->st[i].age); 
                printf("学号: %d\n", p->st[i].num);
                printf("成绩: ");
                for (int j = 0; j < 5; j++) {
                    printf("%d ", p->st[i].score[j]);
                }
                printf("\n");
                return i; 
            }
        }
    } else {
        printf("无效的查询模式。\n");
        return -1;
    }

    printf("学生不存在。\n");
    return -1; 
}


void sortByName(struct class *p) {
    for (int i = 0; i < p->n - 1; i++) {
        for (int j = i + 1; j < p->n; j++) {
            if (strcmp(p->st[i].name, p->st[j].name) > 0) {
            
                struct student temp = p->st[i];
                p->st[i] = p->st[j];
                p->st[j] = temp;
            }
        }
    }
}

void change(struct class *p) {
    int ret, choose;
    ret = search(p, 1); 
    if (ret != -1) {
        while (1) {
            printf("修改学生信息中的哪一项?\n");
            printf("1.姓名\n");
            printf("2.性别\n");
            printf("3.年龄\n");
            printf("4.学号\n");
            printf("5.成绩\n");
            scanf("%d", &choose);

            switch (choose) {
                case 1:
                    printf("输入新的学生姓名:\n");
                    scanf("%s", p->st[ret].name);
                    break;
                case 2:
                    printf("输入新的学生性别:\n");
                    scanf("%s", p->st[ret].sex);
                    break;
                case 3:
                    printf("输入新的学生年龄:\n");
                    scanf("%d", &p->st[ret].age);
                    break;
                case 4:
                    printf("输入新的学生学号:\n");
                    scanf("%d", &p->st[ret].num);
                    break;
                case 5:
                    printf("请输入新的学生成绩:\n");
                    for (int i = 0; i < 5; i++) scanf("%d", &p->st[ret].score[i]);
                    break;
                default:
                    printf("输入错误。\n");
                    continue;
            }
            FILE *fp = fopen("学生管理信息.txt", "w");
            if (fp == NULL) {
                printf("文件打开失败。\n");
                return;
            }

            for (int i = 0; i < p->n; i++) {
                fprintf(fp, "%s %s %d %d ", p->st[i].name, p->st[i].sex, p->st[i].age, p->st[i].num);
                for (int j = 0; j < 5; j++) {  
                    fprintf(fp, "%d ", p->st[i].score[j]);
                }
                fprintf(fp, "\n");
            }
            fclose(fp);
            printf("学生信息已更新。\n");
            break;
        }
    } else {
        printf("没有找到该学生。\n");
    }
}

int delet(struct class *p) {
    int num, ret;

    printf("输入要删除的学生学号:\n");
    scanf("%d", &num);

    ret = search(p, 1);
    if (ret != -1) {
        for (int i = ret; i < p->n - 1; i++) {
            p->st[i] = p->st[i + 1];
        }
        p->n--;

        FILE *fp = fopen("学生管理信息.txt", "w");
        if (fp == NULL) {
            printf("文件打开失败。\n");
            return -1;
        }

        for (int i = 0; i < p->n; i++) {
            fprintf(fp, "%s %s %d %d ", p->st[i].name, p->st[i].sex, p->st[i].age, p->st[i].num);
            for (int j = 0; j < 5; j++) {  
                fprintf(fp, "%d ", p->st[i].score[j]);
            }
            fprintf(fp, "\n");
        }

        fclose(fp);
        printf("学生信息已删除。\n");
        return 0;
    } else {
        printf("没有找到该学号的学生。\n");
        return -1;
    }
}

void load(struct class *p) {
    FILE *fp = fopen("学生管理信息.txt", "r");
    if (fp == NULL) {
        printf("文件打开失败或文件为空。\n");
        return;
    }

    p->n = 0; 
    while (fscanf(fp, "%s %s %d %d %d %d %d %d %d\n", p->st[p->n].name, p->st[p->n].sex, &p->st[p->n].age, &p->st[p->n].num, &p->st[p->n].score[0], &p->st[p->n].score[1], &p->st[p->n].score[2], &p->st[p->n].score[3], &p->st[p->n].score[4]) != EOF) {
        p->n++;
    }

    fclose(fp);
}

int main() {
    int choose, searchMode;
    struct class p = {0};
    load(&p);
    while (1) {
        menu();
        scanf("%d", &choose);

        switch (choose) {
            case 1:
                add(&p);
                load(&p);
                break;
            case 2:
                sortByName(&p);
                view(&p);
                break;
            case 3:
                printf("选择查询方式(1-按学号,2-按姓名):");
                scanf("%d", &searchMode);
                search(&p, searchMode);
                break;
            case 4:
                change(&p);
                load(&p);
                break;
            case 5:
                delet(&p);
                load(&p);
                break;
            case 6:
                return 0;
            default:
                printf("输入错误,请重新输入。\n");
                break;
        }
    }

    return 0;
}

总结一下

  1. AI帮改,自己修改,花了我挺长时间的,还是自己掌握度不够。
  2. 程序不够美观,没有实行清屏操作。
  3. 有时候运行编译器会报错\work\C\learn\collect2.exe [Error] ld returned 1 exit status,妈呀我真的不知道哪里错了,后来发现是这个文件还在后台运行……
    继续努力吧,学的还很浅,没关系,用努力追赶上就好
posted @ 2024-12-24 18:23  chaoxin  阅读(322)  评论(0)    收藏  举报