Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

strstr() for a string that is NOT null-terminated

How do I do the in-place equivalent of strstr() for a counted string (i.e. not null-terminated) in C?

like image 587
user541686 Avatar asked Dec 21 '11 03:12

user541686


People also ask

Does Strstr return null?

Return Value The strstr() function returns a pointer to the beginning of the first occurrence of string2 in string1. If string2 does not appear in string1, the strstr() function returns NULL.

What is strstr () in C?

The strstr() function returns pointer to the first occurrence of the matched string in the given string. It is used to return substring from first match till the last character.

What does Strstr return if failed?

Return value The strstr() function returns the part of the input string searched for, or false if it fails to find the searched string.

Is Strstr in string h?

In C++, std::strstr() is a predefined function used for string handling. string. h is the header file required for string functions. This function takes two strings s1 and s2 as an argument and finds the first occurrence of the sub-string s2 in the string s1.


2 Answers

See if the function below works for you. I haven't tested it thoroughly, so I would suggest you do so.

char *sstrstr(char *haystack, char *needle, size_t length) {     size_t needle_length = strlen(needle);     size_t i;     for (i = 0; i < length; i++) {         if (i + needle_length > length) {             return NULL;         }         if (strncmp(&haystack[i], needle, needle_length) == 0) {             return &haystack[i];         }     }     return NULL; } 
like image 83
Tim Cooper Avatar answered Oct 08 '22 22:10

Tim Cooper


If you're afraid of O(m*n) behaviour - basically, you needn't, such cases don't occur naturally - here's a KMP implementation I had lying around which I've modified to take the length of the haystack. Also a wrapper. If you want to do repeated searches, write your own and reuse the borders array.

No guarantees for bug-freeness, but it seems to still work.

int *kmp_borders(char *needle, size_t nlen){     if (!needle) return NULL;     int i, j, *borders = malloc((nlen+1)*sizeof(*borders));     if (!borders) return NULL;     i = 0;     j = -1;     borders[i] = j;     while((size_t)i < nlen){         while(j >= 0 && needle[i] != needle[j]){             j = borders[j];         }         ++i;         ++j;         borders[i] = j;     }     return borders; }  char *kmp_search(char *haystack, size_t haylen, char *needle, size_t nlen, int *borders){     size_t max_index = haylen-nlen, i = 0, j = 0;     while(i <= max_index){         while(j < nlen && *haystack && needle[j] == *haystack){             ++j;             ++haystack;         }         if (j == nlen){             return haystack-nlen;         }         if (!(*haystack)){             return NULL;         }         if (j == 0){             ++haystack;             ++i;         } else {             do{                 i += j - (size_t)borders[j];                 j = borders[j];             }while(j > 0 && needle[j] != *haystack);         }     }     return NULL; }  char *sstrnstr(char *haystack, char *needle, size_t haylen){     if (!haystack || !needle){         return NULL;     }     size_t nlen = strlen(needle);     if (haylen < nlen){         return NULL;     }     int *borders = kmp_borders(needle, nlen);     if (!borders){         return NULL;     }     char *match = kmp_search(haystack, haylen, needle, nlen, borders);     free(borders);     return match; } 
like image 27
Daniel Fischer Avatar answered Oct 09 '22 00:10

Daniel Fischer