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

C语言结构体数组按ID删除学生函数异常问题求助

学生删除函数的问题分析与修复

问题现象

实现通过ID删除学生的函数时,输入有效ID无法完成删除,反而触发ID无效的提示;当存在3名学生并尝试删除第二名时,会同时输出成功删除和ID无效的提示,且学生并未被真正删除。

原代码

void remove_student()
{
    char removing_id[12];

    printf("\nPlease enter the id of student that you want to remove : ");
    scanf("%11s", removing_id);

    for (int i = 0; i < students_count; i ++)
    {
        if (strcmp(removing_id, student[i].id) == 0)
        {
            for (int j = i; j < students_count; j++)
            {
                strcpy(student[i].first_name, student[i+1].first_name);
                strcpy(student[i].last_name, student[i+1].last_name);
                strcpy(student[i].id, student[i+1].id);
                student[i].average = student[i+1].average;
            }
            students_count --;

            printf("The student removed successfully.");
        } else
        {
            printf("The id is not available!");
            exit(0);
        }
    }
}

问题根源

  1. 循环内直接终止程序的错误逻辑:外层循环的else分支中,只要当前索引的学生ID不匹配,就立刻调用exit(0)终止程序。这意味着只有要删除的是第一个学生时,才会执行删除逻辑;如果目标是后面的学生,第一次循环(i=0)就会触发错误提示并退出,根本无法找到目标学生。
  2. 内层循环变量未正确使用:内层循环声明了变量j,但所有赋值操作都用了i,导致无法将后续学生的内容依次向前覆盖,删除操作完全失效。
  3. 未在删除后终止循环:即使成功找到并删除学生,外层循环仍会继续迭代,可能触发后续错误逻辑。
  4. 内层循环越界访问:内层循环条件j < students_count会导致当j等于students_count-1时,访问student[j+1](即超出数组范围的内存),引发未定义行为。

修复后的代码

void remove_student()
{
    char removing_id[12];

    printf("\nPlease enter the id of student that you want to remove : ");
    scanf("%11s", removing_id);

    int found = 0; // 标记是否找到目标学生
    for (int i = 0; i < students_count; i++)
    {
        if (strcmp(removing_id, student[i].id) == 0)
        {
            // 用j遍历,将后续学生数据向前移位
            for (int j = i; j < students_count - 1; j++)
            {
                strcpy(student[j].first_name, student[j+1].first_name);
                strcpy(student[j].last_name, student[j+1].last_name);
                strcpy(student[j].id, student[j+1].id);
                student[j].average = student[j+1].average;
            }
            students_count--;

            printf("The student removed successfully.");
            found = 1;
            break; // 删除完成后立即跳出循环
        }
    }

    // 循环结束后统一判断是否输出错误信息
    if (!found)
    {
        printf("The id is not available!");
    }
}

关键修改说明

  • 新增found变量:用于标记是否找到目标学生,避免在循环内直接终止程序,改为循环结束后统一处理错误提示。
  • 内层循环修正:正确使用j变量实现数据向前覆盖,确保删除后后续学生的位置正确前移。
  • 调整内层循环边界:改为j < students_count - 1,避免访问超出数组范围的内存。
  • 删除后跳出循环:调用break终止外层循环,防止不必要的迭代和逻辑错误。
  • 错误提示移至循环外:只有当整个循环遍历完所有学生都未找到匹配ID时,才输出ID无效的提示。

内容的提问来源于stack exchange,提问作者Mani Aghaie

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 16:57:53