删除在 C 中具有 char 数组成员的结构数组中的项

delete item in array of struct that has char array member in C

我在 C 中有这个结构,我用它制作了一个数组

//Structure Definition
struct Employee
{
    int Id;
    char Name[20];
    float Salary;
    char Mobile[12];
};

int main()
{
    int emparr_size = 3;
    struct Employee emparr[emparr_size];

    AddAllEmployees(emparr, emparr_size);
    DisplayAllEmployees(emparr, emparr_size);
    EditEmployee(emparr, emparr_size);
    DeleteEmployee(emparr, emparr_size);
}

void AddAllEmployees(struct Employee * emp_ptr, int size)
{
    for(int i=0; i<size; i++)
    {
        printf("Enter Employee %i Id: ", i+1);
        scanf("%i", &emp_ptr->Id);
        printf("Enter Employee %i Name: ", i+1);
        scanf("%s", emp_ptr->Name);
        printf("Enter Employee %i Salary: ", i+1);
        scanf("%f", &emp_ptr->Salary);
        printf("Enter Employee %i Mobile: ", i+1);
        scanf("%s", emp_ptr->Mobile);
        emp_ptr++;
    }

}

void DisplayAllEmployees(struct Employee * emp_ptr, int size)
{
    for(int i=0; i<size; i++)
    {
        printf("Employee %i Id is %i \n",i+1, emp_ptr->Id);
        printf("Employee %i Name is %s \n",i+1, emp_ptr->Name);
        printf("Employee %i Salary is %f \n",i+1, emp_ptr->Salary);
        printf("Employee %i Mobile is %s \n",i+1, emp_ptr->Mobile);
        emp_ptr++;
    }
}


那我要编辑删除 其中一个像这样

void EditEmployee(struct Employee * emp_ptr, int size)
{
    int index;
    printf("Enter Employee Index: ");
    scanf("%i",&index);

    if(index>0 && index<=size)
    {
        printf("new Employee %i Id ",index);
        scanf("%i", &emp_ptr[index-1].Id);
        printf("new Employee %i Name ",index);
        scanf("%s", emp_ptr[index-1].Name);
        printf("new Employee %i Salary ",index);
        scanf("%f", &emp_ptr[index-1].Salary);
        printf("new Employee %i Mobile ",index);
        scanf("%s",  emp_ptr[index-1].Mobile);

    }
    else
    {
        printf("Invalid Index \n");
    }
}

void DeleteEmployee(struct Employee * emp_ptr, int size)
{

    int index;
    printf("Enter Employee Index: ");
    scanf("%i",&index);
    struct Employee temp={0,"",0,""};
    if(index>0 && index<=size)
    {
            emp_ptr[index-1]=temp;
    }
    else
    {
        printf("Invalid Index \n");
    }

}

除删除功能外,一切正常。它只是用上面的空值替换已删除的员工成员:\

我试过这段代码,它通过将数组中的其他项目移动到它的位置来删除员工。

void DeleteEmployee(struct Employee * emp_ptr, int size)
{

    int index;
    printf("Enter Employee Index: ");
    scanf("%i",&index);
    struct Employee temp={0,"",0,""};
    if(index>0 && index<=size)
    {
        for(int i=0; i<size-1; i++) // important  i < size-1
        {
            emp_ptr[index-1].Id=emp_ptr[index+1+i].Id;
            emp_ptr[i+index].Name=emp_ptr[index+1+i].Name;
            emp_ptr[i+index].Salary=emp_ptr[index+1+i].Salary;
            emp_ptr[i+index].Mobile=emp_ptr[index+1+i].Mobile;
            emp_ptr++;
        }
    }
    else
    {
        printf("Invalid Index \n");
    }

}

这让我在编译时出错

error: assignment to expression with array type

那是因为名字和phone成员是char数组:|我不能做作业 所以尝试了这个

for(int i=0; i<size-1; i++) // important  i < size-1
        {
            emp_ptr[i+index].Id=emp_ptr[index+1+i].Id;
            strcpy(emp_ptr[index+1+i].Name,emp_ptr[i+index].Name);
            emp_ptr[i+index].Id=emp_ptr[index+1+i].Salary;
            strcpy(emp_ptr[index+1+i].Mobile,emp_ptr[i+index].Mobile);
            emp_ptr++;
        }

而且效果不佳!!!

我应该为名字和一个做一个循环 phone 还是有另一种不用循环的方法?

因此,在 C 中,您不能像在某些其他(通常是高级)语言中那样从数组中间“删除”某些内容。所以是的,您原来的删除功能实际上只是在所有内容上写“零”,所以它仍然存在,但除此之外是空的。为了删除而向上移动的第二个删除功能通常是高级语言为“更新”具有较少条目的数组而做的事情,并且是合理的。记住要跟踪你的阵列有多满。 IE,当你删除一些东西时,你会想要将上面的东西向下移动,然后跟踪数组中现在只剩下“2”个条目。

重要:这里有两个概念:

  1. 您最初分配的数组的大小。您不想在数组中写入超出此条目的内容(或程序运行良好)。
  2. 任何时候您在其中的条目数。通常您会希望将此值存储在第二个变量中。

我认为你的最后一个例子看起来应该可行,但因为你有一个从 1 开始的 index,你可能想要更改数组索引以在所有地方添加一个 -1

至于复制数据,当你有字符串时,你可能会考虑使用 strncpy 而不是 strcpy,因为它更安全,并且可以防止坏数据在大于存储空间时导致程序崩溃 space(例如,当 Name 大于 20 时)。

最后,C 基本上分配了一块内存供您存储数据。对于结构数组,它分配的是结构大小的 3 倍。所以你实际上可以这样做:

memcpy(&emparr[0], &emparr[1], sizeof(struct Employee));

将数组中n=1项的内容复制到n=0处。这是移动所有内存的更快方法。

但是:如上文#2 所示,您必须跟踪结构中“正在使用”的条目。您实际上不能删除它(如果不将数组重新分配为不同的大小——我不会在这里讨论)。

谢谢,@Wes Hardaker

I think your last example looks like it should work, but because you have an index that starts at 1, you probably want to change the array indexes to add a -1 everywhere.

救了我

因此删除函数将是(无需将数组重新分配为不同的大小:))

void DeleteEmployee(struct Employee * emp_ptr, int size)
{

    int index;
    printf("Enter Employee Index: ");
    scanf("%i",&index);

    if(index>0 && index<=size)
    {
        for(int i=0; i<size-1; i++) // important  i < size-1
        {
            emp_ptr[i+index-1].Id=emp_ptr[index+i].Id;
            //strcpy does'nt prevent bad data from crashing your program when it's bigger than the storage space (for example when Name is bigger than 20).
            
            emp_ptr[i+index-1].Salary=emp_ptr[index+i].Salary;
            strncpy(emp_ptr[i+index-1].Name,emp_ptr[index+i].Name,size);
            strncpy(emp_ptr[i+index-1].Mobile,emp_ptr[index+i].Mobile,size);
            emp_ptr++;
        }
        struct Employee temp={0,"",0,""};
        emp_ptr[index-1]=temp;
    }
    else
    {
        printf("Invalid Index \n");
    }

}