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 $