如何从 C 中的字符串数组中删除特定字符串?
How to delete a specific string from an array of strings in C?
我需要一个函数来接收指向字符串的指针数组及其大小。
然后它应该寻找那些在数组中出现不止一次的字符串——然后我必须删除它们并重新分配数组。
函数应该 return 数组的新大小。
我正在尝试解决这个问题,但不确定哪里出了问题。
我想将每个要删除的字符串移动到数组的末尾,然后删除它,但不确定 "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;
}
目前有"Segmentation fault"错误
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 =
实际上这是一个错误。
糟糕,你的代码问题多多,因为你没有遵守C语言的一些主要规则:
- 每个非静态变量都应初始化(
deleted
呢?)
- 任何被分配的对象都应该被释放(
check
和 temp
。)
- 永远不要更改作为输入参数传递给函数的内容,或者不要期望更改在 return 上可见(
tab
由于下一行必须在此处考虑) .
- 始终分配
realloc
的结果,因为它可能与输入指针 (realloc(tab, sizeof(char*)*(n-deleted));
) 不同。
第一个可能是分段错误的原因,因为 deleted
被单元化了,它的值只是不确定的。但所有问题都应该得到解决。
首先,不要忘记初始化像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)
指针数组(只有一次,不是每次都通过循环)
重新制作示例超出了本答案的范围,因为它看起来实际上是一些学校练习。对不起。我相信其他提示将帮助您更成功地重试该练习。
并思考:在写作之前思考是一个人在这份工作中取得成功的方式。
我需要一个函数来接收指向字符串的指针数组及其大小。 然后它应该寻找那些在数组中出现不止一次的字符串——然后我必须删除它们并重新分配数组。 函数应该 return 数组的新大小。 我正在尝试解决这个问题,但不确定哪里出了问题。
我想将每个要删除的字符串移动到数组的末尾,然后删除它,但不确定 "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;
}
目前有"Segmentation fault"错误
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 =
实际上这是一个错误。
糟糕,你的代码问题多多,因为你没有遵守C语言的一些主要规则:
- 每个非静态变量都应初始化(
deleted
呢?) - 任何被分配的对象都应该被释放(
check
和temp
。) - 永远不要更改作为输入参数传递给函数的内容,或者不要期望更改在 return 上可见(
tab
由于下一行必须在此处考虑) . - 始终分配
realloc
的结果,因为它可能与输入指针 (realloc(tab, sizeof(char*)*(n-deleted));
) 不同。
第一个可能是分段错误的原因,因为 deleted
被单元化了,它的值只是不确定的。但所有问题都应该得到解决。
首先,不要忘记初始化像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)
指针数组(只有一次,不是每次都通过循环)
重新制作示例超出了本答案的范围,因为它看起来实际上是一些学校练习。对不起。我相信其他提示将帮助您更成功地重试该练习。
并思考:在写作之前思考是一个人在这份工作中取得成功的方式。