简体   繁体   English

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

[英]How to delete a specific string from an array of strings in C?

I need a function that receives an array of pointers to strings and it's size. 我需要一个函数,该函数接收一个指向字符串及其大小的指针的数组。 Then it should seek for those strings which occur in the array more than once - then I have to delete them and realloc the array. 然后,它应查找数组中出现的字符串不止一次-然后我必须删除它们并重新分配数组。 Function should return new size of the array. 函数应返回数组的新大小。 I'm trying to solve this, and not sure what`s wrong. 我正在尝试解决此问题,并且不确定出什么问题。

I want to move each string, that I want to delete, to the end of the array and then delete it, but not sure when the "realloc" should happen. 我想将要删除的每个字符串移到数组的末尾,然后将其删除,但是不确定何时应该发生“重新分配”。

#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;
}

For now there is "Segmentation fault" error 目前,存在“分段错误”错误

The reason for the SEGMENTATION FAULT is tab[0] store the address of the variable which stores the actual string. SEGMENTATION FAULT的原因是tab [0]存储存储实际字符串的变量的地址。 Here tab[i] is in for loop,hence when it tries to fetch tab[1] itself memory error. 这里的tab [i]处于for循环中,因此当它尝试获取tab [1]本身的内存错误时会出现此情况。

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

FOR EXAMPLE: 例如:

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

Output 产量

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

Actally it is an error. 实际上,这是一个错误。

Oops, your code contains numerous problems, because you failed to observe some major rules of C language: 糟糕,您的代码包含许多问题,因为您没有遵守C语言的一些主要规则:

  • every non static variable shall be initialized (what about deleted ?) 每个非静态变量都应初始化( deleted怎么办?)
  • any object that was malloced shall be freed (what about check and temp .) 任何已分配的对象都应释放(关于checktemp
  • never change something that was passed as an input parameter to a function, or do not expect the change to be visible on return ( tab has to be considered here because of next line). 永远不要更改作为输入参数传递给函数的内容,或者不要期望该更改在返回时可见(由于下一行,此处必须考虑tab )。
  • allways assign the result of realloc because it can be different from the input pointer ( realloc(tab, sizeof(char*)*(n-deleted)); ). 始终分配realloc的结果,因为它可能不同于输入指针( realloc(tab, sizeof(char*)*(n-deleted)); )。

The first one is probably the cause of the segmentation fault because as deleted is unitialized its value is just undeterminated. 第一个可能是分段错误的原因,因为当deleted被统一后,其值就无法确定。 But all problems should be fixed. 但是所有问题都应该解决。

First of all, don't forget to initialise variables like deleted , as it has been said in other answers. 首先,别忘了像deleted那样初始化变量,如其他答案中所述。

Next, you are supposed to free memory (as you are deleting items) and you only call malloc(3) ). 接下来,应该释放内存(正在删除项目),并且只调用malloc(3) )。 That seems a little counter-common sense, doesn't it? 这似乎有点反常感,不是吗?

Third, you make a lot of string copying in the loops, while it should be more efficient just to move pointers up, so you don't need to realloc the string elements and copy the cell contents (by the way, are you sure those strings will be feed to the function as malloc() d strings? I will assume that as you do) 第三,您在循环中进行了很多字符串复制,尽管向上移动指针应该会更有效率,所以您不需要重新分配字符串元素并复制单元格内容(顺便说一下,您确定那些字符串将作为malloc() d字符串提供给函数?我会像您一样假设)

Fourth, consider sorting the array first, so all the similar strings will be adjacent in the array. 第四,考虑首先对数组进行排序,以便所有相似的字符串在数组中相邻。 This has a cost O(n*log(n)) that, appended to the delete next string if equal (with cost O(n) ) makes total cost O(n*(log(n)+1)) or O(n*log(n)) and not O(n^2) which is your actual cost) 这具有成本O(n*log(n)) ,如果相等(附加成本O(n) ),则将其附加到删除下一个字符串上,从而使总成本O(n*(log(n)+1))O(n*log(n))而不是O(n^2) ,这是您的实际费用)

Once sorted, only the strings deleted should be free(3) d, the pointers moved back to the start of the array as holes get appearing, and finally(when all is finished) you can just realloc(3) the array of pointers (only once, not at every pass through the loop) 排序后,只有删除的字符串才是free(3) d,随着出现空洞,指针移回到数组的开头,最后(当所有步骤完成时)您只需重新realloc(3)指针数组(仅一次,而不是每次通过循环时)

Remaking the example is out of the scope of this answer, as it looks actually some school exercise. 重新制作示例超出了此答案的范围,因为它看起来实际上是一些学校练习。 Sorry for that. 抱歉 I'm sure that the other hints will help you to retry the exercise with more success. 我相信其他提示将帮助您重试该练习,从而获得更大的成功。

And think: thinking before writing is how one succeeds in this job. 并想一想:在写作之前先思考是如何在这项工作中取得成功的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM