重新创建strstr()函数

时间:2018-03-06 12:44:31

标签: c pointers strstr

您好我正在尝试创建自己的strstr()函数,但我无法弄清楚它返回分段错误的原因。我正在尝试在另一个字符串中搜索字符串,然后返回一个指向第一个'相同'信件。任何帮助,将不胜感激。 这是我的代码:

char* ms_search(char *Str1,char* Str2){
    char* p = NULL;
    int i,k=0,j = 0;
    for(i = 0;i < ms_length(Str1); i++){
        if(Str1[i] == Str2[k]){
            if(k == 0){
                p = &Str1[i];
                j= i;
            }
            if(k == ms_length(Str2)){
                break;
            }
            k++;
        }
        else{
            if(Str1[i] == Str2[0]){
                p = &Str1[i];
                k=1;
                j= i;
            }   
            else{
                j=0;
                k = 0;
                p = NULL;
            }
        }
    }
    if(p != NULL){
        Str1[ms_length(Str2)+1] = '\0';
    }
    return &Str1[j];
} 
int main(){
    int i;
    char* p2;
    char* p="lolaaa";
    char* p1= "aaa";
    //char ar2[] = "aaa4";
    //ms_copy(p,p1);
    //printf("%s",p);
    //ms_nconcat(p,p1,3);
    //if(ms_ncompare(p,p1,3) == 1) printf("einai idia");
    p2 = ms_search(p,p1);
    printf("%s",p2);
    return 0;
}

2 个答案:

答案 0 :(得分:2)

  

您好我正在尝试创建自己的strstr()

首先,你必须遵循C标准。

C89 / C99原型是:

char *strstr(const char *s1, const char *s2);

标准strstr()函数不会更改传递的缓冲区。

该功能描述为:

strstr()函数在由s1 s2.字符序列(不包括终止空字符)指向的字符串中找到第一个匹配项>

strstr函数返回指向定位字符串的指针,如果找不到字符串,则返回空指针。如果s2指向长度为零的字符串,则函数返回s1

在标准C中,这可以实现为:

#include <string.h> /* size_t memcmp() strlen() */
char *strstr(const char *s1, const char *s2)
{
    size_t n = strlen(s2);
    while(*s1)
        if(!memcmp(s1++,s2,n))
            return (char *) (s1-1);
    return 0;
}

独立实现如下:

#include <stdio.h>

char *strstr1(const char *str, const char *substring)
{
    const char *a;
    const char *b;

    b = substring;

    if (*b == 0) {
        return (char *) str;
    }

    for ( ; *str != 0; str += 1) {
        if (*str != *b) {
            continue;
        }

        a = str;
        while (1) {
            if (*b == 0) {
                return (char *) str;
            }
            if (*a++ != *b++) {
                break;
            }
        }
        b = substring;
    }

    return NULL;
}

int main (void)
{
  char string[64] ="This is a test string for testing strstr";
  char *p;

  p = strstr1 (string,"test");

  if(p)
  {
    printf("String found:\n" );

    printf ("First occurrence of string \"test\" in \"%s\" is:\n%s", string, p);
  }
  else
  {
    printf("String not found!\n" );
  }

  return 0; 
}

输出:

String found:
First occurrence of string "test" in "This is a test string for testing strstr" is:
test string for testing strstr

答案 1 :(得分:0)

您的独立strstrl是正确的。 我有我的偏好,而你有你的偏好。 两者都不是完美的。 您更喜欢

if ( *b == 0 ) {
    return (char *) s1;
}

我喜欢

 if ( ! *b ) return (char *) s1;

您更喜欢

str += 1;

我喜欢

str++;

您更喜欢

while (1)

我喜欢

for (;;)

如果我根据自己的喜好重写了您的strstrl,我们会得到

char *strstr1(const char *str, const char *substring)
{
  const char *a, *b = substring;

  if ( !*b ) return (char *) str;
  for ( ; *str ; str++) {
    if (*str != *b) continue;
    a = str;
    for (;;) {
      if ( !*b ) return (char *) str;
      if (*a++ != *b++) break;
    }
    b = substring;
  }
  return NULL;
}

请注意,此版本具有相同的代码段

if ( ! *b ) return (char *) str;

在两个位置。我们只能重新安排一次测试吗?

请注意当主角匹配时我们如何进行两次测试

if ( *str != *b )

,然后再次使用相同的主角字符

a = str ; if ( *a++ != *b++)

我们可以重新安排一次测试吗?

下面是我对独立strstr的重写。可能不是 您的样式,但在很多方面与独立的strstr相似。 我的重写更短了,我想相信,更容易理解。

char *strstr(const char *str, const char *substring)
{
  const char *a = str, *b = substring;
  for (;;) {
    if ( !*b ) return (char *) str;
    if ( !*a ) return NULL;
    if ( *a++ != *b++) { a = ++str; b = substring; }
  }
}