You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

二叉搜索树学生系统中动态添加课程结构体数组的问题排查

二叉搜索树学生管理系统课程添加模块问题排查与优化建议

问题描述

正在实现基于二叉搜索树的学生管理系统,在添加课程模块尝试通过动态分配Disciplina结构体数组存储学生课程信息时运行出错,核心代码片段如下:

novo -> disciplinas = malloc(sizeof(Disciplina) * numdisciplinas);
for (int i = 0; i < numdisciplinas; i++){
    printf("Digite o nome da disciplina: ");
    scanf("%s",&novo -> disciplinas[i] -> nome);
    scanf("%c");
    printf("\nDigite o codigo da disciplina: ");
    scanf("%d",&novo -> disciplinas[i] -> codigo);
    printf("\nDigite a nota final da disciplina: ");
    scanf("%f",&novo -> disciplinas[i] -> nota);
    
}

错误原因分析

  1. 结构体成员访问错误:novo->disciplinas是动态分配的Disciplina类型数组,disciplinas[i]是数组中的结构体实例(非指针),必须用.访问成员,而非->。当前代码用disciplinas[i]->nome会直接导致非法内存访问。
  2. 输入缓冲区处理不当:scanf("%c");未指定接收变量,无法正确清空输入缓冲区的换行符,会导致后续scanf读取异常。
  3. 未检查内存分配结果:malloc可能分配失败返回NULL,后续直接操作会引发程序崩溃。

修复后的代码

// 先检查内存分配是否成功
novo->disciplinas = malloc(sizeof(Disciplina) * numdisciplinas);
if (novo->disciplinas == NULL) {
    printf("内存分配失败\n");
    // 根据实际逻辑处理错误,比如返回错误码或终止程序
    return;
}

for (int i = 0; i < numdisciplinas; i++) {
    printf("Digite o nome da disciplina: ");
    // 使用.访问结构体成员
    scanf("%s", novo->disciplinas[i].nome);
    // 清空输入缓冲区残留的换行符
    while(getchar() != '\n');
    
    printf("\nDigite o codigo da disciplina: ");
    scanf("%d", &novo->disciplinas[i].codigo);
    while(getchar() != '\n');
    
    printf("\nDigite a nota final da disciplina: ");
    scanf("%f", &novo->disciplinas[i].nota);
    while(getchar() != '\n');
}

更简便的课程添加实现方式

  1. 改用链表存储课程:避免数组的固定大小限制,添加课程时动态创建Disciplina节点并插入链表,无需预先指定课程数量,灵活性更高。
  2. 封装课程输入逻辑:将单个课程的输入逻辑封装为独立函数,代码结构更清晰:
Disciplina criarDisciplina() {
    Disciplina disc;
    printf("Digite o nome da disciplina: ");
    fgets(disc.nome, sizeof(disc.nome), stdin);
    // 移除fgets读取的换行符
    size_t len = strlen(disc.nome);
    if (len > 0 && disc.nome[len-1] == '\n') {
        disc.nome[len-1] = '\0';
    }
    
    printf("\nDigite o codigo da disciplina: ");
    scanf("%d", &disc.codigo);
    while(getchar() != '\n');
    
    printf("\nDigite a nota final da disciplina: ");
    scanf("%f", &disc.nota);
    while(getchar() != '\n');
    
    return disc;
}

调用时直接在循环中赋值:novo->disciplinas[i] = criarDisciplina();
3. 优化字符串输入:用fgets替代scanf("%s"),支持读取带空格的课程名称,避免输入截断问题。

内容的提问来源于stack exchange,提问作者Entony Maxwell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 03:45:32