我正在编写一个函数来查找子字符串。但我不知道我哪里出错了。 在运行GDB时,我遇到了分段错误。如果有人可以指导我朝正确的方向发展。
这是代码
char *mystrstr(char * s1, const char * s2)
int main(){
char *s1 = "The quick brown fox jumps over the hell lazy dog";
char *s2 = "hello";
char *s4;
s4 = mystrstr(s1,s2);
printf("%s\n",s4); <--- this is where i am Seg. Faulting
return 0;
}
答案 0 :(得分:5)
当s2不是s1的子字符串时,你返回null,然后你试图打印它,这会产生分段错误。
尝试这样的事情:
s4 = mystrstr(s1,s2);
if(s4 != NULL)
printf("%s\n",s4);
答案 1 :(得分:2)
问题是在内部循环中添加索引i+j
以访问s1
。如果你想象i
在你的例子中指向“dog”中的“o”,j
在内循环中从0变为5(长度为“hello”)。这会导致您访问s1[i+j]
以查看字符o
,g
,\0
,垃圾,垃圾
C字符串的好处是它们是空终止的。所以你可以迭代像
这样的字符串for (char* i = s1; *i != 0; i++) {
...
}
即。从s1
的开头迭代,直到找到终止的0字节。在内循环中,这允许您编写以下内容:
const char *j, *k;
for (j = s2, k = i; *j == *k && *j != 0; j++, k++);
if (*j == 0)
return i;
即。 j
从s2
的开头k
开始,i
当前指向s1
内的s2
。只要两个字符串相等,它们就会迭代,并且它们没有到达终止的0字节。如果您确实已达到*j == 0
(i
)的0字节,则表示已找到子字符串。
请注意,您可能希望返回s1
而不是s1
,因为这会为您提供指向所请求的子字符串开始的{{1}}的指针。
答案 2 :(得分:1)
printf("%s\n",s4? s4 : "(NULL)");
答案 3 :(得分:0)
char *s1 = "The quick brown fox jumps over the hell lazy dog";
char *s2 = "hello";
根据mystrstr
*s2
不是*s1
的子字符串,因为您在hello
中找不到*s1
。因此,该方法将返回NULL
。并且无法将NULL
打印为字符串并导致错误。
要验证这一点,请尝试将*s1
替换为:
char *s1 = "The quick brown fox jumps over the hello lazy dog"; // replace hell by hello
输出将是:
The quick brown fox jumps over the hello lazy dog