Find String Function in [ C ]

Viewed 747

Needing a function that would check me for the existence of a substring and give me the location I created this function, I wanted to know if something similar already exists in the C headers and how it works.

This own function give the position where start the substring Hello world! if i search world give 6 If the string is not found then give -1

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

int findfstr(const char mainstring[], const char substring[]){
    // int = findstring(mainstring,substring) give position if found and -1 if not

    int main_length = strlen(mainstring); // Read the mainstring length
    int subs_length = strlen(substring); // Read the substring length
    int where = 0; // Set to 0 the var of start position
    int steps = (main_length - subs_length); //Retrive the numbers of the chars without substring
    int cicle = 0; // Set to 0 the var used for increment steps
    
    
    char found_string[subs_length]; // Set the Array to the substring length
    
    if ( subs_length <= main_length){ // If substring is bigger tha mainstring make error
        while (where == 0){ //loop until var "where are equal to 0"
            
            //Stop loop if and when  cicle is bigger than steps
            if (cicle >= steps && where == 0){ where = -1;} 
            
            //retrive the substring and store in found_string
            strncpy(found_string, mainstring+cicle, subs_length); 
            
            found_string[subs_length] = '\0'; //Add terminator char to end string
            
            //If retrived string are equal to substring then set where with clicle value
            if ((strcmp(found_string, substring) == 0 )) { 
                    where = cicle;
                
            }
            cicle++; //add +1 to cicle
            
            
        }
    
    }else{ printf("\n substring is to big \n"); } //error message
    
    return where; 
}

int main(){

    int fs = 0;

    // This is how use the function
    fs = findfstr("Hello world!","world");


    if ( fs > 0 ){ printf("\n String found and start in: %d", fs);}
    if ( fs < 0 ){ printf("\n String not found value: %d", fs);}
return 0;

}

Output:

String found and start in: 6

2 Answers

I wanted to know if something similar already exists in the C

Yes, there is.

strstr is what you are looking for. See https://man7.org/linux/man-pages/man3/strstr.3.html

If you want the offset from the start of the string just use pointer arithmetic.

Something like:

#include <stdio.h>
#include <string.h>
int main(void){
    char* str ="Hello";
 
    char* needle = strstr(str, "ell");  // Search for "ell" in str
    if (needle)
    {
        int offset = needle - str;  // Calculate the offset
        printf("offset is %d\n", offset);
    }
    else
    {
        // not found...
    }
    return 0;
}

Output:

offset is 1

There is the standard C string function strstr declared like

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

that does in fact the same task. Only its return type differs from the return type of your function.

As for your function then it is too complicated and as any too complicated function has at least a bug that can invoke undefined behavior.

For example you declared a variable length array in this declaration

char found_string[subs_length];

that itself is a bad idea because there can be not enough memory to allocate such an array for big strings.

So the valid range of indices for this array is [0, subs_length). However you are using the value subs_length as an index to access memory beyond the array

found_string[subs_length] = '\0';

Also the type int used as the return type can be not large enough to store a position in a big character array. You have to use the type size_t instead.

Here is a demonstrative program that shows how the function can be defined simpler without defining an intermediate variable length array that requires program resources.

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

char * findfstr( const char *s1, const char *s2 )
{
    const char *p = NULL;
    size_t n1 = strlen( s1 );
    size_t n2 = strlen( s2 );
    
    for ( ; p == NULL && !( n1 < n2 ); --n1 )
    {
        if ( strncmp( s1, s2, n2 ) == 0 )
        {
            p = s1;
        }
        else
        {
            ++s1;
        }
    }

    return ( char * )p;
}

int main(void) 
{
    char s1[] = "Hello World";
    const char *s2 = "Hello";
    
    char *p = findfstr( s1, s2 );
    
    if ( p != NULL ) printf( "%" PRIuPTR "\n", p - s1 );
    
    s2 = "World";
    
    p = findfstr( s1, s2 );
    
    if ( p != NULL ) printf( "%" PRIuPTR "\n", p - s1 );
    
    return 0;
}

The program output is

0
6

To output a difference between two pointers use for example the macro PRIdPTR or PRIuPTR declared in the header <inttypes.h>. To declare a variable that keeps a difference between two pointers use the name ptrdiff_t declared in the header <stddef.h>.

For example

#include <stddef.h>

//...

ptrdiff_t diff = p - s1;
Related