4

我试图创建一个函数来替换str1文本中所有出现的tstr2但我不断收到“缓冲区溢出”错误消息。你能告诉我我的功能有什么问题吗?

#include <stdio.h>
#include <string.h>
#include <assert.h>

//replace all *str1 in *t with *str2, put the result in *x, return *x
char * result(char *str1,char *str2,char *t)
{
    char *x=NULL,*p=t,*r=t;
    x=malloc(400*sizeof(char));
    assert(x!=NULL);
    x[0]='\0';
    r=strstr(t,str1); //r is at the first occurrence of str1 in t, p is at the beginning of t
    while(r!=NULL)
    {
        strncat(x,p,r-p); //copy r-p chars from p to x
        strcat(x,str2); //copy str2 to x
        p=r+strlen(str1); //p will be at the first char after the last occurrence of str1 in t
        r=strstr(r+strlen(str1),str1); //r goes to the next occurrence of str1 in t
    }
    strcat(x,p);
    return x;
}

我没有使用该gets()函数来读取任何char数组。

我的编译器是 gcc 版本 4.6.3


我更新了代码,它可以工作,但结果不是预期的。

main()功能:

int main(void)
{
    char *sir="ab",*sir2="xyz",*text="cabwnab4jkab",*final;
    final=result(sir,sir2,text);
    puts(final);
    free(final);
    return 0;
}

打印字符串:

b

我期望cxyzwnxyz4jkxyz

4

2 回答 2

7

看起来您的strncpy参数混淆了:第二个参数是字符串,而不是要复制的字符数的限制,应该是第三个参数:

 strncpy(x, p, r - p); // copy r - p chars from p to x

此外,您想使用strcat而不是strcpy. 使用strcpy,您只需每次都用替换字符串覆盖结果的内容。使用strcat,请务必\0在开始之前使用 初始化结果。

最后,您x从函数返回对局部变量的引用:您不能这样做,因为函数返回后内存不可用。

于 2012-08-20T22:28:34.390 回答
2

您的代码包含很多奇怪的错误。

首先,x是指向目标缓冲区的指针。出于来的原因,您将所有复制都直接x复制到 ,即所有内容都复制到缓冲区的最开始,覆盖以前复制的数据。这根本没有任何意义。你为什么这样做?您需要创建一个专用指针来保持当前目标位置x并将数据写入该位置(而不是将其写入x)。

我看到您编辑了代码并用连接替换了复制。嗯......即使它可能会解决问题,这仍然是糟糕的设计。strcat/strncat函数在好的 C 代码中没有位置。无论如何,您的代码仍然被破坏,因为您试图strcat在未初始化的缓冲区上使用函数x。您需要先初始化x为空字符串。

其次,搜索替换字符串存在一个更微妙的问题。在循环结束时,您从下一个符号继续搜索r=strstr(r+1,str1),即仅将搜索位置增加 1。我不确定这是否是您想要的。

考虑 作为输入文本,以及替换为aaaa的请求。在这种情况下,您要进行多少次替换?有多少次出现?2个还是3个?如果你想得到结果(2 个替换),你必须增加1 ,而不是 1。aabcaaaaaabcbcrstrlen(str1)

事实上,在你设置的当前实现中,只是从位置p=r+strlen(str1)继续搜索。r+1如我的示例所示,这将导致搜索字符串重叠出现的完全无意义的结果。尝试这个

char *str1="aa",*str2="xyz",*text="aaaa",*final;
final=result(str1,str2,text);

看看会发生什么。

于 2012-08-20T22:51:23.170 回答