Strnstr implementation

I am trying to implement the strnstr function in C (strstr, but it checks the length), for some reason it does not work (there is always no output):

#include <stdio.h> char *searchingFor = "stackdummy"; char *in = "la da\ndoo a da\nnow here comes the stack\nok there it was.\n"; char *strnstr(char *s1, char *s2, int length) { if(s1 == NULL || s2 == NULL) return NULL; printf("searching \n\n\"%s\"\n for %.*s\n", s1, length, s2); char *ss1 = malloc(strlen(s1) + 1); strcpy(ss1, s1); char *ss2 = malloc(length + 1); strncpy(ss2, s2, length); char *result = strstr(ss1, ss2); free(ss1); free(ss2); return result; } int main(void) { printf("found: %s\n", strnstr(in, searchingFor, 5) ? "yes" : "no"); printf("found: %s\n", strnstr(in, searchingFor, 5) ? "yes" : "no"); printf("found: %s\n", strnstr(in, searchingFor, 5) ? "yes" : "no"); return 0; } 
+7
c string strstr
source share
2 answers

The implementation provided by Chris Dodd has the following disadvantages:

  • It defeats the purpose of strnstr in that the while condition uses the unlimited string function strchr
  • It depends on the fact that haystack is NULL, which is a deviation from the usual strnstr implementation, for example, as pointed out by GNU-Darwin
  • A strchr call is an unnecessary function call if strchar not strchar
  • Returns haystack instead of NULL when len is zero, deviation from accepted semantics strstr
  • Returns an empty string instead of haystack when needle has a length of zero

The following implementation resolves the above issues, without being as readable as the GNU-Darwin implementation, and is licensed by Creative Commons:

 #include <string.h> char *strnstr(const char *haystack, const char *needle, size_t len) { int i; size_t needle_len; if (0 == (needle_len = strnlen(needle, len))) return (char *)haystack; for (i=0; i<=(int)(len-needle_len); i++) { if ((haystack[0] == needle[0]) && (0 == strncmp(haystack, needle, needle_len))) return (char *)haystack; haystack++; } return NULL; } 
+6
source share

What about:

 char *strnstr(char *haystack, char *needle, size_t len) { if (len == 0) return haystack; /* degenerate edge case */ while (haystack = strchr(haystack, needle[0])) { if (!strncmp(haystack, needle, len)) return haystack; haystack++; } return 0; } 

If you want haystack not complete to zero, you will need two length arguments:

 char *memmem(char *haystack, size_t hlen, char *needle, size_t nlen) { if (nlen == 0) return haystack; /* degenerate edge case */ if (hlen < nlen) return 0; /* another degenerate edge case */ char *hlimit = haystack + hlen - nlen + 1; while (haystack = memchr(haystack, needle[0], hlimit-haystack)) { if (!memcmp(haystack, needle, nlen)) return haystack; haystack++; } return 0; } 

which is available in GNU libc, although older versions do not work.

+2
source share

All Articles