使用字符串指针数组将字符串中的一个子字符串替换为c中的另一个子字符串

使用字符串指针数组将字符串中的一个子字符串替换为c中的另一个子字符串,c,string,C,String,我试图用另一个子字符串替换字符串中的一个子字符串。然而,我在strcpyp,str2线路上发现了一个分段故障;我不明白为什么。 这是我的密码 #include<stdio.h> #include<string.h> #include<stdlib.h> int main() { char *str[] = {"We will teach you how to", "Move a mountain", "Level a

我试图用另一个子字符串替换字符串中的一个子字符串。然而,我在strcpyp,str2线路上发现了一个分段故障;我不明白为什么。 这是我的密码

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


int main()
{
    char *str[] = {"We will teach you how to",
        "Move a mountain",
        "Level a building",
        "Erase the past",
        "Make a million",
        "...all through C"
    };
    char str1[20], str2[20];
    printf("Enter first string\n");
    scanf("%s", str1);
    printf("Enter second string\n");
    scanf("%s", str2);
    char *news, *t, *p;
    int i;
    if(strlen(str2) > strlen(str1))
    {
        printf("Second string should be smaller than first string\n");
        exit(1);
    }
    for(i = 0; i < 6; i++)
    {
        p = strstr(str[i], str1);
        if(p)
        {
            news = p + strlen(str1);
            strcpy(t,news);
            strcpy(p, s);
            strcat(p,t);
            break;
        }
    }
    printf("the new string is\n");
    for( i = 0; i < 6; i++)
    {
        printf("%s\n", str[i]);
    }
    return 0;
}

您正在复制字符串t,但从未将其初始化为指向任何位置

strcpy(t, news);
这是个坏消息——哦,不,这是坏消息,也是好消息

你还有第二个问题。您试图修改指针str数组中的字符串,但这些是字符串文字。您无法可靠地修改字符串文字。你必须修改一些东西,这样你才不会那样做

p = strstr(str[i], str1);  // Generates a pointer into str[i]
...
strcpy(p, s);    // Modifies str[i] -- unsuccessfully
可能最简单但不一定是最好的修复方法是使用:

char str[][64] = {"We will teach you how to",
    "Move a mountain",
    "Level a building",
    "Erase the past",
    "Make a million",
    "...all through C"
};
我没有花很长时间考虑数组第二维度的正确大小,但是64看起来可能会为字符串的增长留出足够的空间。也许这无关紧要,因为有一条关于第二个字符串的注释必须比第一个字符串短,所以您只处理收缩字符串。很幸运你能做到这一点。如果你的琴弦变大了,你必须小心避免麻烦

正如在a中首先指出的,代码中没有变量s。请确保发布可编译代码

进一步观察内部循环,我们可以看到各种各样的问题:

新闻=p+strlenstr1;赋值意味着在str[i]中发现str1后,新闻指向str[i]的尾部。 您将不确定数量的信息从新闻复制到未初始化指针t指向的空间中。这是堆芯转储的第一个源。 将未定义的变量s复制到p上。既然在长度检查后没有使用str2,那么这就是str2吗?这是堆芯转储的第二个源。 在从s复制材质之后,从t复制材质。若你们还并没有转储核心,这可能是第三个核心转储源,但若你们还并没有转储核心,这也不会触发一个。 您可能需要:

char *p = strstr(str[i], str1);
if (p != 0)
{
    char t[64];
    strcpy(t, p + strlen(str1));
    strcpy(p, str2);
    strcat(p, t);
}

这远不是防止溢出的证据,但更接近可靠。

我冒昧地对代码进行了适当的缩进,以使代码更易于阅读。请以后自己试试。t指针指向的是什么?看看strcpyt,新闻;内存分配了吗?这段代码编译了吗?@vinay这个问题向我保证了-1。protip确保您的代码按照此处发布的方式干净地编译,并学习使用valgrind。@t0mm13b或mcheck,或mtrace,或常识,或…没有变量s-刚刚注意到@vinay请仔细检查你的代码,看看有没有这些小问题,有趣的是,你从来没有说过它编译失败?如果代码是从其他地方复制的,然后决定在这里发布,你不会感到惊讶。。。是的,那个strcpyt,新闻;断层的来源是否正确?这并不奇怪……我之前的“呃”评论并不完全准确。尽管如此,还是有一个假设,即发布的代码将被编译。看看分析-如果你能被打扰,我不会责怪你如果你不能被打扰。我已经阅读了你的分析,它绝对正确+1.如果只是,如果,那么实际上把它放回OP上说Yo,这段代码编译得干净吗?请在提交问题之前进行验证。。在这一点上,我不确定OP是否真正理解代码,因此我对复制意大利面发表了评论。。。。