如何从C中的字符串数组中删除特定的字符串?

时间:2019-02-14 11:33:49

标签: c arrays realloc

我需要一个函数,该函数接收指向字符串及其大小的指针的数组。 然后,它应查找数组中出现的字符串不止一次-然后我必须删除它们并重新分配数组。 函数应返回数组的新大小。 我正在尝试解决此问题,但不确定出什么问题。

我想将要删除的每个字符串移动到数组的末尾,然后将其删除,但是不确定何时应该发生“重新分配”。

#include<stdio.h>
#include<stdlib.h>

int DeleteString(char** tab, int n){
    char* check=malloc(sizeof(char)*100);
    int deleted;
    int i,j,g,h;

    for(i=0;i<n;i++){
        strcpy(check, tab[i]);
        for(j=0;j<n;j++){
            if(strcmp(check, tab[j]) == 0){     
                deleted++;
                char* temp = malloc(sizeof(char)*100);
                for(h=j;h<n-1;h++){
                    strcpy(temp, tab[h+1]);
                    strcpy(tab[h+1], check);
                    strcpy(tab[h], temp);       
                }
            }

            if(deleted>0){
                realloc(tab, sizeof(char*)*(n-deleted));
            }
        }
    }
    return n-deleted;
}

目前有“细分错误”错误

3 个答案:

答案 0 :(得分:0)

SEGMENTATION FAULT的原因是tab [0]存储存储实际字符串的变量的地址。 这里的tab [i]处于for循环中,因此尝试获取tab [1]本身的内存错误。

for(i=0;i<n;i++){
    strcpy(check, tab[i]);...}

例如:

 char *foo = "something";
 char **ptr2;
 ptr2 = &foo;
 printf("check = %s", *ptr2); 
 for(int i=0;i<9;i++){  
   printf(" check = %c",  ptr2[i]);
 }

输出

check = something check = 4check = �check = pcheck =

实际上是一个错误。

答案 1 :(得分:0)

糟糕,您的代码包含许多问题,因为您没有遵守C语言的一些主要规则:

  • 每个非静态变量都应初始化(Book会怎样?)
  • 任何已分配的对象都应被释放(deletedcheck这样。)
  • 从不更改作为输入参数传递给函数的内容,或者不希望更改在返回时可见(temp在这里,因为要使用下一行)。
  • 始终分配tab的结果,因为它可能与输入指针(realloc)不同。

第一个可能是分段错误的原因,因为realloc(tab, sizeof(char*)*(n-deleted));被单元化时,其值只是不确定的。但是所有问题都应该得到解决。

答案 2 :(得分:0)

首先,不要忘记初始化deleted之类的变量,如其他答案中所述。

接下来,您应该释放内存(正在删除项目),并且只调用malloc(3)。似乎有点反常感,不是吗?

第三,您在循环中进行了很多字符串复制,而将指针向上移动应该会更加高效,因此您无需重新分配字符串元素并复制单元格内容(顺便说一句,您确定这些字符串将作为malloc() d字符串提供给函数吗?我会像您一样假设)

第四,考虑先对数组排序,以便所有相似的字符串在数组中相邻。这有一个成本O(n*log(n)),如果相等则附加到删除下一个字符串(成本为O(n)),则总成本为O(n*(log(n)+1))O(n*log(n))而不是O(n^2)是您的实际费用)

排序后,仅应删除free(3) d的字符串,当出现空洞时指针将移回数组的开头,最后(所有操作完成后)您只需realloc(3)指针数组(仅一次,而不是每次通过循环时)

重新制作示例超出了此答案的范围,因为它看起来实际上是一些学校练习。抱歉我相信其他提示将帮助您重试该练习,从而获得更大的成功。

再想一想:在写作之前要思考的是一个人在这项工作中是如何成功的。