【问题标题】:delete item in array of struct that has char array member in C在 C 中删除具有 char 数组成员的结构数组中的项目
【发布时间】:2021-08-16 00:31:58
【问题描述】:

我在 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

那是因为姓名和电话成员是 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++;
        }

它不能正常工作!!!

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

【问题讨论】:

  • 你应该使用 strcpy 将字符串分配给另一个字符串
  • 更好的删除方法是创建一个函数,将源结构复制到目标结构,并将其用于移位
  • 如果数组中有三个项,则项的索引应为 0、1 或 2。在进行数组索引之前,通常不应减去 1。您正在为可怕的“减一”错误做好准备
  • @TimRandall 我假设索引将作为 2 之类的位置输入 --> 数组中的第二项,所以我想减去 1。
  • @JatinParmar 所以你的意思是把 for 循环变成一个需要大小、数组、索引的函数!我应该如何更改其中的代码?请给我更多细节。

标签: arrays c pointers struct char


【解决方案1】:

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

重要:这里有两个概念:

  1. 最初分配的数组的大小。你不想写超出数组中的这个条目(或程序开始繁荣)。
  2. 您在任何时候拥有的条目数。通常,您需要将此值存储在第二个变量中。

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

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

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

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

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

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

【讨论】:

    【解决方案2】:

    谢谢,@韦斯哈达克

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

    这救了我

    所以删除函数将是(无需将数组重新分配到不同的大小:))

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-07
      • 2011-12-16
      • 2011-04-11
      • 1970-01-01
      • 2020-04-13
      • 2012-11-21
      • 2014-05-01
      • 1970-01-01
      相关资源
      最近更新 更多