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

C语言数组元素删除异常:员工管理系统删除操作总是删除最后一个元素

C语言数组元素删除异常:员工管理系统删除操作总是删除最后一个元素

刚学C语言写数组操作遇到这种问题太正常了,我帮你把代码里的几个关键错误揪出来,看完你就明白为什么总是删最后一个元素了!

问题1:字符串移动用了判断运算符而非赋值,且字符串不能直接用=赋值

你的删除函数里这行代码是核心bug:

for (int i = pos; i < NOE; i++) Name[i] == Name[i + 1];
  • 首先,==是相等判断运算符,不是赋值!这行代码只是在判断两个字符串是否相等,完全没有做任何元素向前移动的操作。
  • 其次,C语言里的字符数组(字符串)不能直接用=赋值,必须用strcpy函数来完成字符串内容的拷贝。

这就导致循环执行后数组元素根本没挪位置,只是把NOE减了1——相当于直接“截断”了数组的最后一个元素,所以看起来总是删除了最后一个员工。

问题2:只处理了Name数组,未同步处理ID数组

你删除员工时只想着移动Name数组,但完全没管ID数组,这样后续Name和ID就会对应不上,数据直接乱掉。

问题3:缺少索引合法性检查(可选但关键)

用户输入的pos可能超出有效范围(比如负数、大于等于当前员工数),直接用的话会导致数组越界,程序轻则输出乱码,重则崩溃。

修正后的完整代码(重点看Delete函数)

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

// 全局变量(小项目临时用没问题,后续可以学用结构体+参数传递优化)
char Name[100][50];
int ID[100], NOE;

void Register(){
    printf("\n\n请输入要注册的员工数量: ");
    scanf("%d", &NOE );
    for (int i = 0; i < NOE; i++) {
        printf("\n\n请输入第%d位员工的姓名: ", i + 1);
        scanf("%s", Name[i]); // Name[i]本身就是字符数组首地址,不用加&
        printf("\n\n请输入第%d位员工的ID: ", i + 1);
        scanf("%d", &ID[i]);
        printf("\n\n注册成功!\n\n ");
    }
    printf("\n");
}

// 完全修正后的删除函数
void Delete(){
    if (NOE == 0) {
        printf("\n\n当前没有员工记录可以删除!\n");
        return;
    }

    printf("\n\n当前员工列表: ");
    for (int i = 0; i < NOE; i++)
        printf("||%s(ID:%d)|| ", Name[i], ID[i]);
    printf("\n\n");

    int pos;
    printf("请输入要删除的索引(从0开始,比如第一个员工是0): ");
    scanf("%d", &pos);

    // 检查输入的索引是否合法
    if (pos < 0 || pos >= NOE) {
        printf("\n\n输入的索引无效,请输入0到%d之间的数!\n", NOE-1);
        return;
    }

    printf("\n\n正在删除记录...\n");
    // 从pos位置开始,将后面的元素向前移动一位
    for (int i = pos; i < NOE - 1; i++) {
        strcpy(Name[i], Name[i + 1]); // 用strcpy真正拷贝字符串
        ID[i] = ID[i + 1]; // 同步移动ID数组,保证数据对应
    }
    NOE--; // 员工总数减1

    printf("\n\n删除后的员工列表: ");
    for (int i = 0; i < NOE; i++)
        printf("||%s(ID:%d)|| ", Name[i], ID[i]);
    printf("\n\n");
}

void Display(){
    if (NOE == 0) {
        printf("\n\n当前没有员工记录可以显示!\n");
        return;
    }
    printf("\n\n当前员工记录: ");
    for (int i = 0; i < NOE; i++)
        printf("||%s %d|| ", Name[i], ID[i]);
    printf("\n\n");
}

int main(){
    int Choice;
    do{
        printf("\n1. 注册员工记录\n");
        printf("\n2. 删除员工记录\n");
        printf("\n3. 显示员工记录\n");
        printf("\n4. 退出程序\n");
        printf("\n\n请输入你的选择: ");
        scanf("%d", &Choice);
        switch(Choice){
            case 1:
                Register();
                break;
            case 2:
                Delete();
                break;
            case 3:
                Display();
                break;
            case 4:
                printf("\n\n正在退出程序...\n\n");
                exit(0);
            default:
                printf("\n\n无效的选择!\n\n");
        }
    } while(Choice != 4);
    return 0;
}

关键修正点说明

  1. 用strcpy实现字符串移动:替换掉原来的判断语句,真正把后面的员工姓名拷贝到前一个位置。
  2. 同步处理ID数组:移动姓名的同时,把对应的ID也往前移,保证姓名和ID始终一一对应。
  3. 调整循环条件:改成i < NOE - 1,避免i+1越界访问数组的无效区域。
  4. 增加边界检查:判断用户输入的索引是否合法,同时处理没有员工记录的特殊情况,让程序更健壮。
  5. 提示语优化:明确告诉用户索引是从0开始的,减少输入错误的概率。

这样修改后,你就能准确删除指定位置的员工记录啦!


内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 11:40:29