简体   繁体   English

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

[英]delete item in array of struct that has char array member in C

I have this struct in C and I made an array from it我在 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++;
    }
}


then I want to edit and delete one of it like so然后我想像这样编辑和删除其中一个

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

}

everything works fine except the delete function.除了删除 function 外,一切正常。 It just replaces the deleted employee member with empty values like above:\它只是用上面的空值替换已删除的员工成员:\

I have tried this code that deletes an employee by shifting other items in the array to its position like so.我已经尝试过这段代码,它通过将数组中的其他项目转移到它的 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");
    }

}

this gives me an error in the compilation这给了我一个编译错误

error: assignment to expression with array type

that's because the name and phone member are arrays of char:|那是因为姓名和电话成员是char的arrays:| and I can't do assignment so tried this我不能做作业所以试过这个

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

and it doesn't work fine!!!而且效果不好!!!

Should I make a loop for the name and one phone or there is another way to do this without loops?我应该为姓名和一部电话制作一个循环,还是有另一种没有循环的方法?

So, in C you can't "delete" something from the middle of an array like you can in some other (typically higher level) languages.因此,在 C 中,您不能像在其他一些(通常是更高级别)语言中那样从数组中间“删除”某些东西。 So yes, your original delete function is really just writing "zeros" over everything so its still there, but otherwise empty.所以是的,你原来的删除 function 实际上只是在所有内容上写“零”,所以它仍然存在,但其他地方是空的。 Your second delete function of moving things up in order to delete is frequently what the higher level languages are doing to "update" an array with less entries, and is reasonable.您的第二次删除 function 将事物向上移动以删除通常是高级语言正在执行的“更新”具有较少条目的数组,并且是合理的。 Remember to keep track of how full your array is.请记住跟踪您的阵列有多满。 IE, when you delete something you'll want to move the upper stuff down, and then keep track that there are now only '2' entries left in the array. IE,当您删除某些内容时,您需要将上面的内容向下移动,然后跟踪数组中现在只剩下“2”个条目。

Important: there are two concepts here:重要:这里有两个概念:

  1. the size of the array that you originally allocated.您最初分配的数组的大小。 You don't want to write beyond this entry in the array (or program go boom).您不想在数组中写入超出此条目的内容(或程序 go boom)。
  2. The number of entries you have in it at any time.您随时拥有的条目数。 Typically you'll want to store this value in a second variable.通常,您会希望将此值存储在第二个变量中。

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

As for copying data, when you have strings you might look at using strncpy instead of strcpy as it's safer and will prevent bad data from crashing your program when it's bigger than the storage space (for example when Name is bigger than 20).至于复制数据,当您有字符串时,您可能会考虑使用strncpy而不是strcpy ,因为它更安全,并且可以防止坏数据在大于存储空间时(例如,当Name大于 20 时)使程序崩溃。

Finally, C is basically allocated a block of memory for you to store your data in. For an array of structures, it's allocating 3 times the size of your structure.最后,C 基本上分配了一块 memory 供您存储数据。对于结构数组,它分配的大小是结构大小的 3 倍。 So you can actually do something like this:所以你实际上可以做这样的事情:

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

to copy the contents of the n=1 entry in the array to the n=0 spot.将数组中 n=1 条目的内容复制到 n=0 点。 It's a faster way to move all the memory.这是移动所有 memory 的更快方法。

But: like indicated in #2 above, you must keep track of what entries are "in use" in the structure.但是:就像上面 #2 中指出的那样,您必须跟踪结构中“正在使用”的条目。 You can't actually delete it (without reallocating an array to a different size -- which I won't get into here).您实际上无法删除它(无需将数组重新分配为不同的大小——我不会在这里讨论)。

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

that saved me那救了我

so the delete function will be (without reallocating an array to a different size:) )所以删除 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