实现strnstr

Jim*_*may 10 c string strstr

我试图将strnstr函数实现为C(strstr,但它会检查长度),由于某种原因它不起作用(输出始终为no):

#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;
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*ham 9

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

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

以下实现解决了上述问题,而不像GNU-Darwin实现那样难以阅读,并且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;
}
Run Code Online (Sandbox Code Playgroud)