实现strnstr

我试图将一个strnstr函数实现为C(strstr,但它检查长度),由于某种原因它不起作用(输出总是没有):

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

Chris Dodd提供的实现具有以下缺点:

  1. 它违背了strnstr的目的,因为while条件使用无界字符串函数strchr
  2. 它取决于haystack是NULL终止,这是与strnstr的通常实现的strnstr ,例如由GNU-Darwin提供的
  3. strchar没有内联时,对strchr的调用是一个不必要的函数调用
  4. len为零时,返回haystack而不是NULL ,这是与接受的strstr语义的偏差
  5. needle长度为零时,返回空字符串而不是haystack

以下实现解决了上述问题,而不像GNU-Darwin实现那样难以阅读,并且Creative Commons获得许可:

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

怎么样:

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

如果你希望haystack不被null终止,你需要两个长度args:

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

这在GNU libc中可用,但旧版本已损坏。