我正在尝试用另一个子字符串替换字符串中的子字符串。但是,我在strcpy行(p,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;
}
答案 0 :(得分:2)
您正在复制到字符串t
,但您从未将其初始化为指向任何位置。
strcpy(t, news);
这是坏消息 - 哦,不,这是不好的t
和好消息。
你还有第二个问题。您正在尝试修改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看起来它可能留下足够的空间让你稍微增长一些字符串。也许这没关系,因为有关于第二个字符串的注释必须比第一个字符串短,所以你只处理缩小的字符串。幸运的是你能够做到这一点。如果你的琴弦能够成长,你必须小心避免麻烦。
正如t0mm13b中comment首次提到的那样,代码中没有变量s
。请确保您发布可编辑的代码。
进一步研究内循环,我们可以看到各种各样的问题:
news = p + strlen(str1);
分配意味着在news
中找到str[i]
后,str1
指向str[i]
的尾部。news
中的不确定数量的信息复制到未初始化指针t
指向的空间中。这是核心转储的第一个来源。s
复制到p
上。这是str2
,因为长度检查后没有使用str2
吗?这是核心转储的第二个来源。t
复制材料后,从s
复制材料。如果你还没有转储核心,这可能是核心转储的第三个来源(虽然如果你还没有转储核心,这也不会触发核心)。您可能需要:
char *p = strstr(str[i], str1);
if (p != 0)
{
char t[64];
strcpy(t, p + strlen(str1));
strcpy(p, str2);
strcat(p, t);
}
这远不是溢出的证明,而是更接近声音。