Alex ander bro 2024-05-27 12:36 采纳率: 0%
浏览 8

c语言学生学籍管理系统的创建

我用C语言创建一个学生学籍管理系统,第一次运行的时候,我添加一个学生,然后保存到文件中,再查询这个学生,该学生的相关信息都能被查到且正确但是在第二次运行的时候,仍然查询这个学生,却惊讶地发现这名学生其他信息都是能被查出来,却只有各科成绩都变成了0,这显然是错误的,但是找不到问题,求解答:
以下是我整个c语言代码:

//1.有主界面和各功能界面;
// 2.能存储学生学籍信息;
// 3.能存储学生各门成绩信息(成绩的判定,特别是补缓考的分值查阅学校的规定);
// 4.能实时给出基于分值的绩点信息显示(按照巢湖学院绩点计算方法计算);
// 5.给出基于绩点的排名显示;6.完成数据示例,可以实现所有数据的查询、新增、修改、删除等。
//主线任务:基于2023级软工专业学生学籍,给出2023 - 2024学年第1学期绩点.
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define M 10//2023级软工专业学生第一学期的考试科目数目
#define N 62//最大学生数
#define lenmax 100
//用结构体来存储学生学籍信息
typedef struct {
    int sID;//学号
    char name[lenmax];//姓名
    char  gender[lenmax + 1];//性别
    int age;//年龄
    int score[M];//存储各科成绩
    float DKgrapoint[M];//存放单科绩点的数组用来求真正的绩点
    int retest[M];//用0和1区分是补缓考还是首次考
    float grapoints;//绩点
    int sortgrap;//绩点排名
}student;
student students[N];
//以下是函数声明
void load();
void showmenu();
void search();
void add_student();
void modify();
void remove();
void save();//
float DK_Grapoint(int score);//计算学生的单科绩点
float avegrapoint(float DKgrapoint[]);//计算平均绩点
int Sort_grap(float grapoint);
float credit[M] = { 2,4.5,1,2.5,2,6,3,3,1,0.5 };//创建一个存储着各科学分的一个数组
int stu_nums = 0;//设置当前的已经录入的学生人数
int main()
{
    load();
    while (1)
    {
        showmenu();
    }
    system("pause");
    return 0;

}
void showmenu()
{
    int num;
    printf("\n\n");
    printf("————————————————————————————————————-\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("请选择菜单的编号:");
    scanf_s("%d", &num);//输入各个功能对应的序号以此来实现相应的功能
    switch (num) {
    case 1:search();
        break;
    case 2:add_student();
        break;
    case 3:modify();
        break;
    case 4:remove();
        break;
    case 5:save();
        break;
    case 6:printf("退出程序成功!\n");
        exit(0);
    default:
        printf("请在1-6之间选择\n");
        system("pause");//提示完成之后显示按任意键继续
    }
}
void add_student()
{
    student new_student;
    printf("请输入学生的学号:");
    scanf("%d", &new_student.sID);
    printf("请输入学生的姓名:");
    scanf_s("%s", new_student.name, (int)sizeof(new_student.name));
    printf("请输入学生的性别:");
    scanf_s("%s", &new_student.gender, (int)sizeof(new_student.gender));
    printf("请输入学生的年龄:");
    scanf_s("%d", &new_student.age);
    printf("请输入学生的各科考试状态:0代表正常考试,1代表补缓考\n");
    printf("请按照心理、c语言、职业规划、大英、计导、高数、线代、思政、体育、口语这十门课的顺序依次进行考试状态和考试成绩的录入:\n");
    for (int i = 0; i < M; i++)
    {
        printf("请输入第%d科考试状态", i + 1);
        scanf_s("%d", &new_student.retest[i]);
    }
    printf("请输入学生的各科成绩:");
    for (int j = 0; j < M; j++)
    {
        scanf_s("%d", &new_student.score[j]);
        if (new_student.retest[j] != 0 && new_student.score[j] >= 60)//补缓考成绩
            new_student.score[j] = 60;
        if (new_student.retest[j] != 0 && new_student.score[j] < 60)
            new_student.score[j] = 0;
    }
    for (int k = 0; k < M; k++)
        new_student.DKgrapoint[k] = DK_Grapoint(new_student.score[k]);
    printf("学生的绩点为:");
    new_student.grapoints = avegrapoint(new_student.DKgrapoint);//得出绩点
    printf("%f", new_student.grapoints);
    new_student.sortgrap = Sort_grap(new_student.grapoints);
    students[stu_nums++] = new_student;
    printf("学生信息添加成功,立即把数据信息保存到文件中\n");
}
int Sort_grap(float grapoint)//给绩点排名
{
    int count = 0;
    for (int i = 0; i < stu_nums - 1; i++)
    {
        if (grapoint > students[i].grapoints)
            count++;
    }
    return stu_nums - count + 1;
}
float DK_Grapoint(int score)//将单科成绩转为单科绩点
{
    float a;
    a = (float)(score % 10) * 0.1;//a表示绩点的小数的部分
    int b = (score / 10) - 5;
    return a + b;
}
float avegrapoint(float DKgrapoint[M])
{
    float sum1 = 0;//计算各个学科学分累积之和
    float sum2 = 0;
    for (int i = 0; i < M; i++)
    {
        sum1 = sum1 + credit[i];
        sum2 = sum2 + credit[i] * DKgrapoint[i];
    }
    return sum2 / sum1;
}
void search()  //查找已知学号的学生信息
{
    
    int id;//定义已知学号
    int flag = 0;//来判断是否查找到该学生
    printf("请输入要查询学生的学号:\n");
    scanf_s("%d", &id);
    for (int i = 0; i < N; i++)
    {
        if (students[i].sID == id)
        {
            printf("学号:%d  姓名:%s  性别:%s  年龄:%d 绩点%f 绩点排名%d  \n", students[i].sID, students[i].name, students[i].gender, students[i].age, students[i].grapoints, students[i].sortgrap);
            printf("以下是各科成绩:\n");
            for (int j = 0; j < M; j++)
            {
                printf("%d\n", students[i].score[j]);
            }
            flag = 1;
        }
    }
    if (flag != 1)
        printf("NO Found!\n");//没有查询到该学生的信息
    else
        printf("查找到");
}
void modify()
{
    long int a;
    int item;
    printf("请输入要改学生数据的学号:\n");
    scanf_s("%ld", &a);
    for (int i = 0; i < stu_nums; i++)
    {
        if (students[i].sID == a)
        {
            printf("1.修改名字:\n");
            printf("2.修改性别:\n");
            printf("3.修改年龄:\n");
            printf("4.修改成绩\n");
            printf("5.修改绩点\n");
            printf("6.修改绩点排名\n");
            printf("0.End of program!\n");
            while (1)
            {
                printf("请选择\n");
                scanf_s("%d", &item);//自定义选择要修改的具体数据
                switch (item)
                {
                case 1:
                    printf("Please input new name:\n");
                    scanf_s("%s", students[i].name, (int)sizeof(students[i].name));
                    break;
                case 2:
                    printf("Please input sex:\n ");
                    scanf_s("%s", &students[i].gender, (int)sizeof(students[i].gender));
                    break;
                case 3:
                    printf("Please input new age:\n");
                    scanf_s("%d", &students[i].age);
                    break;
                case 4:
                    printf("please input new score:\n");
                    printf("对心理、c语言、职业规划、大英、计导、高数、线代、思政、体育、口语依次修改\n");
                    for (int j = 0; j < M; j++)
                    {
                        scanf_s("%d", &students[i].score[j]);
                        if (students[i].score[j] >= 60 && students[i].retest[j] == 1)
                            students[i].score[j] = 60;
                        if (students[i].score[j] < 60 && students[i].retest[j] == 1)
                            students[i].score[j] = 0;
                    }
                    break;
                case 5:
                    for (int k = 0; k < M; k++)
                        students[i].DKgrapoint[k] = DK_Grapoint(students[i].score[k]);
                    students[i].grapoints = avegrapoint(students[i].DKgrapoint);
                    break;
                case 6:
                    students[i].sortgrap = Sort_grap(students[i].grapoints);
                    break;
                default:
                    printf("输入错误\n");
                }
                if (item == 0)
                    break;
            }
        }

    }
}
void remove()
{
    int index = -1;
    int student_id;
    int i;
    printf("输入学生的学号:");
    scanf_s("%d", &student_id);
    for (i = 0; i < stu_nums; i++)
    {
        if (students[i].sID == student_id)
        {
            index = i;
            break;
        }
    }
    if (index == -1)
    {
        printf("学号不存在\n");
        return;
    }
    for (i = index; i < stu_nums; i++)
    {
        students[i] = students[i + 1];
    }
    stu_nums--;
    printf("删除学生信息成功\n");
}
void save()
{
    FILE* fp;
    fp = fopen("student.txt", "w");
    if (fp == NULL) {
        printf("文件打开失败!");
        return;
    }
    fprintf(fp, "%d  %s  %s  %d  %f  %d\n ", students[stu_nums - 1].sID, students[stu_nums - 1].name, students[stu_nums - 1].gender, students[stu_nums - 1].age, students[stu_nums - 1].grapoints, students[stu_nums - 1].sortgrap);
    for (int i = 0; i < M; i++)
        fprintf(fp, "%d", students[stu_nums - 1].score[i]);
    fclose(fp);
    printf("学生信息保存成功!");
}
void load() {
    FILE* fp;
    char filename[] = "student.txt";
    int i = 0;

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

    // 读取文件中的数据
    while (fscanf(fp, "%d %s %s %d %f %d",
        &students[i].sID,
        students[i].name,
        students[i].gender,
        &students[i].age,
        &students[i].grapoints,
        &students[i].sortgrap) != EOF) {
        i++;
    }

    // 关闭文件
    fclose(fp);

    // 更新学生人数
    stu_nums = i;
}



  • 写回答

1条回答 默认 最新

  • 阿里嘎多学长 2024-05-27 13:03
    关注

    以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


    从您提供的代码来看,问题可能出在save函数和load函数的实现上。首先,我们来分析这两个函数:

    save函数

    save函数中,您只保存了最后一个学生的全部信息,并且保存时并没有将所有学生的各科成绩写入文件。这会导致每次程序运行时,只有最后一个学生的信息被保存,而其他学生的信息丢失。

    void save()
    {
        FILE* fp;
        fp = fopen("student.txt", "w");
        if (fp == NULL) {
            printf("文件打开失败!");
            return;
        }
        for (int i = 0; i < stu_nums; i++) // 应该遍历所有学生
        {
            fprintf(fp, "%d  %s  %s  %d  %f  %d\n ", students[i].sID, students[i].name, students[i].gender, students[i].age, students[i].grapoints, students[i].sortgrap);
            for (int j = 0; j < M; j++)
                fprintf(fp, "%d ", students[i].score[j]); // 需要添加空格分隔成绩
            fprintf(fp, "\n"); // 添加换行符以便区分不同的学生记录
        }
        fclose(fp);
        printf("学生信息保存成功!");
    }
    

    load函数

    load函数中,您只读取了文件中的第一条记录,并且没有正确地读取学生的各科成绩。

    void load() {
        FILE* fp;
        char filename[] = "student.txt";
        int i = 0;
    
        // 打开文件
        fp = fopen(filename, "r");
        if (fp == NULL) {
            printf("无法打开文件 %s\n", filename);
            return;
        }
    
        // 读取文件中的数据
        while (fscanf(fp, "%d %s %s %d %f %d",
            &students[i].sID,
            students[i].name,
            students[i].gender,
            &students[i].age,
            &students[i].grapoints,
            &students[i].sortgrap) != EOF)
        {
            // 读取各科成绩
            for (int j = 0; j < M; j++)
            {
                fscanf(fp, "%d", &(students[i].score[j]));
            }
            i++; // 移动到下一个学生的位置
        }
    
        // 关闭文件
        fclose(fp);
    
        // 更新学生人数
        stu_nums = i;
    }
    

    其他建议

    1. 文件格式:确保文件中的格式与读取和写入时的格式一致。
    2. 内存分配:注意gender字段在结构体中的定义,您使用了char gender[lenmax + 1],这可能会导致越界访问,因为lenmax已经是一个足够大的值,不需要再加1。
    3. 错误处理:在读取和写入文件时,增加更多的错误处理逻辑,以确保程序的健壮性。
    4. 测试:在修改代码后,进行充分的测试,确保所有功能都能正常工作。

    参考资料

    通过上述修改,您应该能够解决学生成绩在第二次运行时变为0的问题。如果问题仍然存在,建议逐步调试并检查每个函数的实现。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 5月27日