C 如何删除所有匹配项
现在,这个函数正在从列表中删除用户给出的姓氏,但我需要它删除与用户给出的姓氏匹配的所有名称,而不仅仅是第一次出现的用户输入,并且需要释放已删除名称的分配内存。我该怎么做C 如何删除所有匹配项,c,C,现在,这个函数正在从列表中删除用户给出的姓氏,但我需要它删除与用户给出的姓氏匹配的所有名称,而不仅仅是第一次出现的用户输入,并且需要释放已删除名称的分配内存。我该怎么做 int deleteR(char**Fname,char **Lname,float *score,int count) { int i=0,j=0; char *Lastname; printf("\n Enter the Last Name of the
int deleteR(char**Fname,char **Lname,float *score,int count)
{
int i=0,j=0;
char *Lastname;
printf("\n Enter the Last Name of the Student you would like to delete from the records. ");
Lastname = (char *)malloc(15 * sizeof(char));
printf("\nLast Name: ");
scanf("%s",Lastname);
int counter = count;
for(i=0;i<count-1;i++)
{
if(strcmp(Lname[i],Lastname)==0)
{
for(j=i;j<count;j++)
{
Lname[j]=Lname[j+1];
Fname[j]=Fname[j+1];
score[j]=score[j+1];
}
counter--;
}
}
count=counter;
return count;
}
int deleteR(字符**Fname,字符**Lname,浮点*分数,整数计数)
{
int i=0,j=0;
char*Lastname;
printf(“\n输入要从记录中删除的学生的姓氏。”);
Lastname=(char*)malloc(15*sizeof(char));
printf(“\n上一个名称:”);
scanf(“%s”,Lastname);
int计数器=计数;
对于(i=0;i如果您在j上的循环删除了条目,因为您以后在i上的循环中没有更改计数,那么您将访问已经检查过的值,并且可能会因为删除而被释放
您还存在内存泄漏,因为您为Lastname分配了内存,但从未释放它,事实上,没有理由不将Lastname作为堆栈中的数组。此外,您的scanf可以写入Lastname而不受大小限制
您不需要像以前那样有两个嵌入式循环,只有一个循环足以移动管理索引的条目进行写入,另一个循环用于读取:
int deleteR(char**Fname, char **Lname, float *score, int count)
{
char lastname[16];
printf("\nEnter the Last Name of the Student you would like to delete from the records: ");
if (scanf("%15s", lastname) == 1) {
int i;
/* that first loop to search if the lastname is present */
for (i = 0; i < count; ++i) {
if (!strcmp(Lname[i], lastname)) {
/* at least present one time, update lists */
int futureCount = count - 1;
int j;
/* it seems you want to free removed resources */
free(Lname[i]);
free(Fname[i]);
/* that loop to move useful elements */
for (j = i + 1; j < count; ++j) {
if (strcmp(Lname[j], lastname)) {
/* still usefull */
Lname[i] = Lname[j];
Fname[i] = Fname[j];
score[i] = score[j];
i += 1;
}
else {
/* useless */
/* it seems you want to free removed resources */
free(Lname[j]);
free(Fname[j]);
futureCount -= 1;
}
}
return futureCount;
}
}
}
else
puts("EOF");
return count;
}
汇编和执行:
pi@raspberrypi:/tmp $ gcc -Wall d.c
pi@raspberrypi:/tmp $ ./a.out
Enter the Last Name of the Student you would like to delete from the records: Chopin
new lists:
Wolfgang Amadeus Mozart : 0
Johann Sebastian Bach : 1
Leopold Mozart : 2
Johann Christian Bach : 3
Ludwig van Beethoven : 4
pi@raspberrypi:/tmp $ ./a.out
Enter the Last Name of the Student you would like to delete from the records: Mozart
new lists:
Johann Sebastian Bach : 1
Johann Christian Bach : 3
Ludwig van Beethoven : 4
pi@raspberrypi:/tmp $
删除名称后,下列项的索引会向下移动。但随后您会递增i
,因此您会跳过移动到旧i
位置的元素。这是在迭代数组时从数组中删除时出现的常见错误。@Barmar您能给我更多关于如何修复该问题的提示吗?Sry i'm n我不擅长用代码思考。free(Lname[i])
--这会让人大吃一惊。因为调用者很可能已经以char Lname[10][100]
的方式分配了内存。我宁愿返回条目数,让调用者处理分配/解除分配。@lenik显然情况并非如此,因为(1)在问题tte OP写入“已删除名称的分配内存”中,(2)在不释放资源的情况下,在某些条目上多次访问并不成问题,因为OP定义就是这样,(3)OP从未在S.O.中提出该问题。注意,我还提出了一条评论,明确指出:-)@bruno非常感谢!chanu you welcome,希望您理解代码中的错误以及我的代码为何有效,您将来很有可能需要类似的练习。祝您编码愉快
pi@raspberrypi:/tmp $ gcc -Wall d.c
pi@raspberrypi:/tmp $ ./a.out
Enter the Last Name of the Student you would like to delete from the records: Chopin
new lists:
Wolfgang Amadeus Mozart : 0
Johann Sebastian Bach : 1
Leopold Mozart : 2
Johann Christian Bach : 3
Ludwig van Beethoven : 4
pi@raspberrypi:/tmp $ ./a.out
Enter the Last Name of the Student you would like to delete from the records: Mozart
new lists:
Johann Sebastian Bach : 1
Johann Christian Bach : 3
Ludwig van Beethoven : 4
pi@raspberrypi:/tmp $