繁体   English   中英

删除 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");
    }

}

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

我已经尝试过这段代码,它通过将数组中的其他项目转移到它的 position 来删除员工,就像这样。

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

那是因为姓名和电话成员是char的arrays:| 我不能做作业所以试过这个

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++;
        }

而且效果不好!!!

我应该为姓名和一部电话制作一个循环,还是有另一种没有循环的方法?

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

重要:这里有两个概念:

  1. 您最初分配的数组的大小。 您不想在数组中写入超出此条目的内容(或程序 go boom)。
  2. 您随时拥有的条目数。 通常,您会希望将此值存储在第二个变量中。

我认为您的最后一个示例看起来应该可以工作,但是因为您有一个从 1 开始的index ,您可能希望更改数组索引以在任何地方添加-1

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

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

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

将数组中 n=1 条目的内容复制到 n=0 点。 这是移动所有 memory 的更快方法。

但是:就像上面 #2 中指出的那样,您必须跟踪结构中“正在使用”的条目。 您实际上无法删除它(无需将数组重新分配为不同的大小——我不会在这里讨论)。

谢谢,@韦斯哈达克

我认为您的最后一个示例看起来应该可以工作,但是因为您有一个从 1 开始的索引,您可能希望更改数组索引以在任何地方添加 -1。

那救了我

所以删除 function 将是(没有将数组重新分配到不同的大小:))

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");
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM