所以我开始从一本书中学习C,其中一个练习是创建一个函数,它将取2个字符串并从第一个字符串中删除第二个字符串中的字符。
我们的窗框没有学习指针,所以我想如果没有它们,这是可能的, 但是当我尝试运行我的代码时,我很喜欢。
代码:
#include <stdio.h>
#include <string.h>
char squis(char string[], char sub[])
{
int i, c;
char ret_string[strlen(string)];
int map[strlen(string)];
for(i=0; i<= strlen(string);i++)
map[i] = -1;
for(i=0; i<= strlen(sub);i++)
{
while(string[c]!='\0')
{
if (string[c]==sub[i])
map[c] = c;
c++;
}
c=0;
}
for(i=0; i<= strlen(string);i++)
{
if (map[i]==-1)
ret_string[c++] = string[i];
}
ret_string[c] ='\0';
return ret_string[0];
}
int main()
{
char string[] = "string";
char remove[] = "sasas";
printf("%s",squis(string,remove));
return 0;
}
我在C中使用新手,所以我认为问题在于我对C的工作方式缺乏了解。
非常感谢你的帮助: - )
更新:它似乎是在函数结束时返回的问题。
当我在函数内部打印ret_string
时,函数似乎运行良好(除了一个让函数忽略子字符串中的第一个字符的bug,但我稍后会处理它),但当我尝试返回时在main函数中打印它的数组失败。
在C中有返回数组的具体规则吗?
答案 0 :(得分:3)
这是一个明显的问题:
int map[strlen(string)];
for(i=0; i<= strlen(string);i++)
map[i] = -1;
您创建一个strlen(string)
个字符数组,然后初始化数组中的strlen(string) + 1
个字符。写出超出数组的范围会导致undefined behavior,任何事情都可能发生。
将循环条件更改为小于<
。你可能应该在你的所有循环中都这样做。
您遇到与ret_string
类似的问题,这将是您返回的字符串。它最多只有strlen(string)
个字符,但是你需要为字符串终止符添加一个字符,这样数组的长度需要strlen(string) + 1
。
然后你遇到的问题是squis
函数只返回一个字符,但在printf
调用中你将这个单个字符视为一个字符串。这应该让你的编译器尖叫警告你。如果你通过简单地返回ret_string
来解决这个问题,你将会遇到另一个未定义行为的情况,然后返回一个指向局部变量的指针,该函数在函数退出时超出范围,所以返回的指针不再有效。如果您决定在堆上分配ret_string
,那么当前调用会导致内存泄漏,因此指针不会被保存,因此您可以释放已分配的内存。