Alex ander bro 2024-06-09 20:57 采纳率: 0%
浏览 0

c语言学生学籍管理系统

我用c语言编写的学生学籍管理系统出现了这样的问题:第一次运行该系统的任何功能都能实现,但是第二次运行执行查找操作的时候查找不到原来已经添加过的学生。请帮我详细看看我的源代码,到底是哪里出错了,调试了一天了没有解决。


```c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct StudentInfo {
    char name[50];
    int id;
    char sex[30];
    int age;
    char major[50];
    int sort;
    float grapoint;
};
struct Course {
    char name[20];
    float score;
    float credit;
    float DKgrapoint;
    int ismakeup;//用来区分补缓考
};
typedef  struct student
{
    struct StudentInfo  info;
    struct Course  courses[10];
}stu;
typedef struct  Lnode
{
    stu  data;
    struct Lnode* next;
}linklist;
void load(linklist*& L);
void showmenu(linklist*& L);
void search(linklist* L);
void add(linklist*& L);
void modify(linklist* L);
void remove(linklist* L);
void save(linklist*& L);
void initlist(linklist*& L);
void insert(linklist*& L, linklist* p);
float compute_DKgpa(float score);
float compute_gpa(linklist* newnode);
int sort_grap(linklist* p, linklist* L);
int main()
{
    linklist* L;
    initlist(L);
    load(L);
    while (1)
    {
        showmenu(L);
    }
    system("pause");
    return 0;
}
void showmenu(linklist*& L)
{
    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("*                      7.退出系统                            *\n");
    printf("—————————————————————————————————————\n");
    printf("请选择菜单的编号:");
    scanf_s("%d", &num);//输入各个功能对应的序号以此来实现相应的功能
    switch (num) {
    case 1:search(L);
        break;
    case 2:add(L);
        break;
    case 3:modify(L);
        break;
    case 4:remove(L);
        break;
    case 5:save(L);
        break;
    case 6:printf("退出程序成功!\n");
        exit(0);
    default:
        printf("请在1-6之间选择\n");
        system("pause");//提示完成之后显示按任意键继续
    }
}
void initlist(linklist*& L)
{
    L = (linklist*)malloc(sizeof(linklist));
    L->next = NULL;
}
void insert(linklist*& L, linklist* p)//尾插法插入节点
{
    linklist* q;
    q = L;
    while (q->next)
    {
        q = q->next;
    }
    p->next = NULL;
    q->next = p;
}
void add(linklist*& L)
{
    linklist* p;
    p = L;
    int num;
    printf("请输入该名学生的学号:");
    scanf_s("%d", &num);
    while (p->next)
    {
        if (p->data.info.id == num)
        {
            printf("该学生已存在\n");
            break;
        }
        p = p->next;
    }
    if (!p->next)
    {
        linklist* newnode = (linklist*)malloc(sizeof(linklist));
        newnode->data.info.id = num;
        printf("请输入学生名字:");
        scanf_s("%s", newnode->data.info.name, _countof(newnode->data.info.name));
        printf("性别:");
        scanf_s("%s", newnode->data.info.sex, _countof(newnode->data.info.sex));
        printf("年龄:");
        scanf_s("%d", &newnode->data.info.age);
        printf("专业:");
        scanf_s("%s", &newnode->data.info.major, _countof(newnode->data.info.major));
        for (int i = 0; i < 10; i++)
        {
            printf("请输入第%d学科的相关信息:", i + 1);
            printf("请输入该科的名称:");
            scanf_s("%s", newnode->data.courses[i].name, _countof(newnode->data.courses[i].name));
            printf("请输入该门课的考试状态,0代表正常考试,1代表补缓考:");
            scanf_s("%d", &newnode->data.courses[i].ismakeup);
            printf("请输入该门课的考试成绩:");
            scanf_s("%f", &newnode->data.courses[i].score);
            printf("请输入该门课程的学分:");
            scanf_s("%f", &newnode->data.courses[i].credit);
            if (newnode->data.courses[i].ismakeup && newnode->data.courses[i].score >= 60)
                newnode->data.courses[i].score = 60;
            if (newnode->data.courses[i].ismakeup && newnode->data.courses[i].score < 60)
                newnode->data.courses[i].score = 0;
            newnode->data.courses[i].DKgrapoint = compute_DKgpa(newnode->data.courses[i].score);//单科成绩转为绩点
        }
        newnode->data.info.grapoint = compute_gpa(newnode);
        newnode->data.info.sort = sort_grap(newnode, L);
        insert(L, newnode);
        printf("添加学生成功,别忘了保存学生信息!");
    }
}
float compute_DKgpa(float score)
{
    return((score / 10) - 5 + ((int)score % 10) * 0.1);
}
float compute_gpa(linklist* newnode)
{
    double sum1 = 0;
    double sum2 = 0;
    for (int i = 0; i < 10; i++)
    {
        sum1 = sum1 + newnode->data.courses[i].credit;//计算学分总和
        sum2 = sum2 + newnode->data.courses[i].credit * newnode->data.courses[i].DKgrapoint;
    }
    return sum2 / sum1;
}
int sort_grap(linklist* p, linklist* L)
{
    int count1 = 0;
    int count2 = 0;
    linklist* q = L;
    while (q)
    {
        if (p->data.info.grapoint > (q->data.info.grapoint))
            count1++;
        q = q->next;
        count2++;
    }
    return count2 - count1 + 1;
}
void modify(linklist* L)
{
    int num;
    int flag;
    int choice;
    linklist* p;
    p = L;
    printf("请输入您要修改的学生的学号:\n");
    scanf_s("%d", &num);
    while (p->next)
    {
        if (p->data.info.id == num)
        {
            flag = 1;
            printf("请输入您要修改的信息选项:0.学号 1.姓名 2.性别 3.年龄 4.专业 5.各学科6.绩点 7.绩点排名 \n");
            scanf_s("%d", &choice);
            switch (choice)
            {
            case 0:
                printf("请输入您要修改的学号:");
                scanf_s("%d", &num);
                printf("修改的学号为:%d\n", num);
                p->data.info.id = num;
                printf("修改学号成功!\n");
                break;
            case 1:
                char name[50];
                printf("修改后的名字为:\n");
                scanf_s("%s", name, 50);
                strcpy_s(p->data.info.name, name);
                break;
            case 2:
                char sex[50];
                printf("请输入您要修改的性别");
                scanf_s("%s", sex, 50);
                strcpy_s(p->data.info.sex, sex);
                printf("修改性别成功!\n");
                break;
            case 3:
                int age;
                printf("请输入您要修改的年龄:");
                scanf_s("%d", &age);
                p->data.info.age = age;
                printf("修改年龄成功!\n");
                break;
            case 4:
                char major[50];
                printf("请输入您要修改的专业:");
                scanf_s("%s", major, 50);
                strcpy_s(p->data.info.major, major);
                printf("修改专业成功!");
                break;
            case 5:
                char course[50];
                printf("请输入你想修改的课程:\n");
                scanf_s("%s", course, 50);
                for (int i = 0; i < 10; i++)
                {
                    if (course == p->data.info.major)
                    {
                        printf("请输入你想要修改的课程信息的相关选项:0表示课程名1表示学分2表示补缓考状态3表示成绩(包含单科绩点)\n");
                        int num2;
                        scanf_s("%d", &num2);
                        switch (num2)
                        {
                        case 0:
                            char name2[50];
                            printf("请输入你要重新修改的课程名:");
                            scanf_s("%s", name2, _countof(name2));
                            strcpy_s(p->data.courses[i].name, name2);
                            break;
                        case 1:
                            float credit;
                            printf("请输入你想修改的学分为:\n");
                            scanf_s("%f", &credit);
                            p->data.courses[i].credit = credit;
                            break;
                        case 2:
                            int ismakeup;
                            printf("请输入该门课程的补缓考状态,0表示正常,1表示补缓考:\n");
                            scanf_s("%d", &ismakeup);
                            p->data.courses[i].ismakeup = ismakeup;
                            break;
                        case 3:
                            float score;
                            printf("请重新输入该门课程的成绩:\n");
                            scanf_s("%f", &score);
                            p->data.courses[i].score = score;
                            p->data.courses[i].DKgrapoint = compute_DKgpa(score);
                            printf("该门课程的绩点已经自动修改!");
                            break;
                        default:
                            printf("输入错误,请重新进行修改:\n");
                            break;
                        }
                    }
                }
                break;
            case 6:p->data.info.grapoint = compute_gpa(p);
                printf("该名学生的绩点已经修改成功:\n");
                break;
            case 7:
                printf("请修改该名学生的绩点排名:\n");
                p->data.info.sort = sort_grap(p, L);
                printf("修改绩点排名成功:\n");
                break;
            default:printf("请输入正确的选项:\n");
                break;
            }
        }
        p = p->next;
    }
    if (flag != 0)
        printf("该学生不存在:\n");
}
void remove(linklist* L)
{
    int num;
    int flag;
    printf("请输入您要删除的学生的学号:");
    scanf_s("%d", &num);
    linklist* pre = L;
    linklist* p = pre->next;
    while (p)
    {
        if (p->data.info.id == num)
        {
            flag = 1;
            pre->next = p->next;
            free(p);
            printf("成功删除学生!\n");
            break;
        }
        pre = p;
        p = p->next;
    }
    if (flag != 0)
        printf("这个学生不存在!\n");
}
void search(linklist* L)
{
    int num;
    int flag;
    printf("1.按学号查询:\n");
    printf("2.按姓名查询:\n");
    printf("请输入查询方式:");
    scanf_s("%d", &flag);
    if (flag == 1)
    {
        printf("请输入该学生的学号:");
        scanf_s("%d", &num);
        linklist* p = L->next;
        while (p != NULL)
        {
            if (p->data.info.id == num)
            {
                printf("学号:%d\n", p->data.info.id);
                printf("姓名:%s\n", p->data.info.name);
                printf("性别:%s\n", p->data.info.sex);
                printf("年龄:%d\n", p->data.info.age);
                printf("绩点:%f\n", p->data.info.grapoint);
                printf("绩点排名:%d\n", p->data.info.sort);
                printf("专业:%s\n", p->data.info.major);
                for (int i = 0; i < 10; i++)
                    printf("%s:  %f   绩点:%f\n", p->data.courses[i].name, p->data.courses[i].score, p->data.courses[i].DKgrapoint);
                break;
            }
            p = p->next;
        }
        if (p == NULL)
            printf("该学生不存在\n");
    }
    else
    {
        char name[60];
        printf("请输入该学生的姓名:");
        scanf_s("%s", name, 60);
        linklist* q = L->next;
        while (q)
        {
            if (q->data.info.name == name)
            {
                printf("学号:%d\n", q->data.info.id);
                printf("姓名:%s\n", q->data.info.name);
                printf("性别:%s\n", q->data.info.sex);
                printf("年龄:%d\n", q->data.info.age);
                printf("绩点:%f\n", q->data.info.grapoint);
                printf("绩点排名:%d\n", q->data.info.sort);
                printf("专业:%s\n", q->data.info.major);
                for (int i = 0; i < 10; i++)
                    printf("%s:  %f   绩点:%f\n", q->data.courses[i].name, q->data.courses[i].score, q->data.courses[i].DKgrapoint);
                break;
            }
            q = q->next;
        }
        if (!q)
            printf("该学生不存在\n");
    }
}
void save(linklist*& L)
{
    FILE* fp;
    linklist* p = L->next;
    if ((fp = fopen("student.txt", "w")) == NULL)
    {
        printf("不能打开此文件,请按任意键退出\n");
        exit(1); //异常退出
    }
    while (p)
    {
        struct Course {
            char name[20];
            double score;
            double credit;
            double DKgrapoint;
            int ismakeup;//用来区分补缓考
        };
        fprintf(fp, "%d %s %s %d %f %d %s\n", p->data.info.id, p->data.info.name, p->data.info.sex, p->data.info.age, p->data.info.grapoint, p->data.info.sort, p->data.info.major);
        for (int i = 0; i < 10; i++)
            fprintf(fp, "%s %f %f %f %d\n", p->data.courses[i].name, p->data.courses[i].score, p->data.courses[i].credit, p->data.courses[i].DKgrapoint, p->data.courses[i].ismakeup);
        p = p->next;
    }
    printf("保存成功:\n");
    fclose(fp);
}
char name1[50];
int id;
char sex[30];
int age;
char major[50];
int sort;
float grapoint;
char name2[20];
float score;
float credit;
float DKgrapoint;
int ismakeup;//用来区分补缓考
    void load(linklist * &L) {
        FILE* file = fopen("student.txt", "r");
        if (file == NULL) {
            printf("Error opening file: student.txt\n");
            return;
        }

        // 清空链表
        while (L->next) {
            linklist* temp = L->next;
            L->next = temp->next;
            free(temp);
        }

        while (fscanf(file, "%d %s %s %d %s %d %f",
            &id, name1, sex, &age, major, &sort, &grapoint) == 7) {
            linklist* newNode = (linklist*)malloc(sizeof(linklist));
            newNode->data.info.id = id;
            strcpy(newNode->data.info.name, name1);
            strcpy(newNode->data.info.sex, sex);
            newNode->data.info.age = age;
            newNode->data.info.grapoint = grapoint;
            newNode->data.info.sort = sort;
            strcpy(newNode->data.info.major, major);
            for (int i = 0; i < 10; i++) {
                if (fscanf(file, "%s %f %f %f %d",
                    name2, &score, &credit, &DKgrapoint, &ismakeup) == 5) {
                    strcpy(newNode->data.courses[i].name, name2);
                    newNode->data.courses[i].score = score;
                    newNode->data.courses[i].credit = credit;
                    newNode->data.courses[i].DKgrapoint = DKgrapoint;
                    newNode->data.courses[i].ismakeup = ismakeup;
                } 
            }
            insert(L, newNode);
        }
        fclose(file);
    }

```

  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-06-09 20:57
    关注

    引自免费微信小程序:皆我百晓生

    从你提供的代码来看,主要的问题在于search函数中的字符串比较方法不正确,以及load函数中的数据读取逻辑可能存在缺陷。让我们逐一分析并修正这些问题。

    search函数中的字符串比较

    search函数中,你使用了==来比较字符串,这是不正确的。==用于比较指针地址,而不是字符串内容。正确的做法是使用strcmp函数来比较两个字符串是否相等。例如:

    if (strcmp(q->data.info.name, name) == 0)
    

    load函数中的数据读取逻辑

    load函数中,你尝试从文件中读取数据并构建链表。然而,在读取课程数据时,你没有检查所有10个课程是否都被正确读取。如果文件中的数据不足,那么fscanf将不会读取到预期的数据,导致newNode->data.courses[i]可能包含未初始化的数据。

    为了修复这个问题,你需要确保在读取每个学生的所有课程之前,文件流仍然有效。你可以在循环内部添加一个条件检查,例如:

    for (int i = 0; i < 10 && fscanf(file, "%s %f %f %f %d", name2, &score, &credit, &DKgrapoint, &ismakeup) == 5; i++) {
    

    这样,只有当fscanf成功读取了5个数据项时,循环才会继续,否则会提前结束。

    修改后的searchload函数

    下面是修改后的searchload函数:

    void search(linklist* L)
    {
        int num;
        int flag;
        printf("1.按学号查询:\n");
        printf("2.按姓名查询:\n");
        printf("请输入查询方式:");
        scanf_s("%d", &flag);
        if (flag == 1)
        {
            printf("请输入该学生的学号:");
            scanf_s("%d", &num);
            linklist* p = L->next;
            while (p != NULL)
            {
                if (p->data.info.id == num)
                {
                    // 输出学生信息
                    break;
                }
                p = p->next;
            }
            if (p == NULL)
                printf("该学生不存在\n");
        }
        else
        {
            char name[60];
            printf("请输入该学生的姓名:");
            scanf_s("%s", name, 60);
            linklist* q = L->next;
            while (q)
            {
                if (strcmp(q->data.info.name, name) == 0)
                {
                    // 输出学生信息
                    break;
                }
                q = q->next;
            }
            if (!q)
                printf("该学生不存在\n");
        }
    }
    
    void load(linklist * &L) {
        FILE* file = fopen("student.txt", "r");
        if (file == NULL) {
            printf("Error opening file: student.txt\n");
            return;
        }
    
        // 清空链表
        while (L->next) {
            linklist* temp = L->next;
            L->next = temp->next;
            free(temp);
        }
    
        while (fscanf(file, "%d %s %s %d %s %d %f",
            &id, name1, sex, &age, major, &sort, &grapoint) == 7) {
            linklist* newNode = (linklist*)malloc(sizeof(linklist));
            // 初始化newNode
            for (int i = 0; i < 10 && fscanf(file, "%s %f %f %f %d", name2, &score, &credit, &DKgrapoint, &ismakeup) == 5; i++) {
                // 初始化newNode->data.courses[i]
            }
            insert(L, newNode);
        }
        fclose(file);
    }
    

    这些修改应该能解决你遇到的问题。确保在你的项目中全面测试这些更改,以验证它们是否满足你的需求。如果还有其他问题,建议你逐行检查代码,特别是数据读写和结构体赋值的部分,确保所有数据都正确地被处理和存储。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 6月9日