Recreate the strstr() function

风流意气都作罢 提交于 2021-02-07 09:38:47

问题


Hello i am trying to make my own strstr() function and i can't figure out why it is returning a segmentation fault.I am trying to search a string within another string and then return a pointer to the first 'same' letter. Any help would be appreciated. This is my code:

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;
}

回答1:


Hello i am trying to make my own strstr()

First of all you have to follow the C standard.

The C89/C99 prototype is:

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

Standard strstr() function will NOT change the passed buffers.

The functionality is described as:

strstr() function locates the first occurrence in the string pointed to by s1 of the sequence of characters (excluding the terminating null character) in the string pointed to by s2.

The strstr function returns a pointer to the located string, or a null pointer if the string is not found. If s2 points to a string with zero length, the function returns s1.

In standard C, this can be implemented as:

#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;
}

The standalone implementation is given below:

#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; 
}

Output:

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



回答2:


Your standalone strstrl is correct. I have my preferences, and you have yours. Neither is perfect. You prefer

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

I prefer

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

You prefer

str += 1;

I prefer

str++;

You prefer

while (1)

I prefer

for (;;)

If I rewrite your strstrl with my preferences, we get

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;
}

Note that this version has the same snippet

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

in two locations. Can we rearrange to do that test only once?

Note how we do two tests when lead character matches

if ( *str != *b )

and again later for the same lead char

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

Can we rearrange that to do a single test?

My rewrite of your standalone strstr is below. It might not be your style, but it is in many ways similar to your standalone strstr. My rewrite is shorter and, I want to believe, easier to understand.

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; }
  }
}


来源:https://stackoverflow.com/questions/49131175/recreate-the-strstr-function

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!