删除在 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 开始的 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");
}
}
我在 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 开始的 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");
}
}