2011-03-15 5 views
3

C를 사용하면 null이 포함될 수있는 버퍼 내부의 하위 문자열을 찾아야합니다.null이 포함 된 버퍼에서 하위 문자열을 검색하려면 어떻게해야합니까?

haystack = "Some text\0\0\0\0 that has embedded nulls". 
needle = "has embedded"r 

내가 문자열, 또는 null의 시작을 반환해야, similat()는 않는 strstr합니다 :

request_segment_end = mystrstr(request_segment_start, boundary); 

당신이 알고있는 기존의 구현이 있습니까?

나는, 그대로 여기에 검증되지 않은 복사 한 구글의 codesearch에 memove의 구현을 발견

업데이트,

/* 
* memmem.c 
* 
* Find a byte string inside a longer byte string 
* 
* This uses the "Not So Naive" algorithm, a very simple but 
* usually effective algorithm, see: 
* 
* http://www-igm.univ-mlv.fr/~lecroq/string/ 
*/ 

#include <string.h> 

void *memmem(const void *haystack, size_t n, const void *needle, size_t m) 
{ 
     const unsigned char *y = (const unsigned char *)haystack; 
     const unsigned char *x = (const unsigned char *)needle; 

     size_t j, k, l; 

     if (m > n || !m || !n) 
       return NULL; 

     if (1 != m) { 
       if (x[0] == x[1]) { 
         k = 2; 
         l = 1; 
       } else { 
         k = 1; 
         l = 2; 
       } 

       j = 0; 
       while (j <= n - m) { 
         if (x[1] != y[j + 1]) { 
           j += k; 
         } else { 
           if (!memcmp(x + 2, y + j + 2, m - 2) 
            && x[0] == y[j]) 
             return (void *)&y[j]; 
           j += l; 
         } 
       } 
     } else 
       do { 
         if (*y == *x) 
           return (void *)y; 
         y++; 
       } while (--n); 

     return NULL; 
} 
+1

이 경우 "경계"란 무엇입니까? – templatetypedef

+0

[ESMAJ] (http://www-igm.univ-mlv.fr/~lecroq/string/index.html)에 설명 된 방법 중 하나를 구현할 수 있습니다. – pmg

답변

4

"문자열"에 null 문자가 포함되어 있다고 생각하지 않습니다. 문자열은 널로 끝나기 때문에 첫 번째 발생은 문자열의 끝을 표시합니다. 게다가, 단어 뒤에 "nulls" 이후의 null 종결자가 더 이상의 문자를 가지고 있지 않다는 것을 어떻게 말할 것인가.

버퍼에서 검색한다는 의미라면 나에게 더 적합 할 것입니다. null 문자를 무시하고 그냥 길이에 의존하는 버퍼를 검색하면됩니다. 기존의 구현은 모르지만 간단한 구현을 쉽게 수행 할 수 있어야합니다. 물론 필요에 따라 더 나은 검색 알고리즘을 사용하십시오.

char *search_buffer(char *haystack, size_t haystacklen, char *needle, size_t needlelen) 
{ /* warning: O(n^2) */ 
    int searchlen = haystacklen - needlelen + 1; 
    for (; searchlen-- > 0; haystack++) 
     if (!memcmp(haystack, needle, needlelen)) 
      return haystack; 
    return NULL; 
} 

char haystack[] = "Some text\0\0\0\0 that has embedded nulls"; 
size_t haylen = sizeof(haystack)-1; /* exclude null terminator from length */ 
char needle[] = "has embedded"; 
size_t needlen = sizeof(needle)-1; /* exclude null terminator from length */ 
char *res = search_buffer(haystack, haylen, needle, needlen); 
+0

네 말이 맞아, 내 용어가 틀렸어. 나는 주어진 문자열에 대한 버퍼를 검색하려고했다. 코드 제공에 감사드립니다. 바쁜 지금 테스트. – crafter

+0

그렇지 않으면 좋은 답변에 대한 몇 가지 세부 정보를 정리하기위한 메모는 알고리즘이 선형 검색이며 실제로 O (n)가 아닌 O (n^2)가 아니라면 데이터를 제외하고는 더 잘할 수 있다고 생각하지 않습니다. 귀하의 검색은 어떻게 든 주문됩니다. 또한 거기에 하나의 오류로 떨어져 있다고 생각 첫 번째 비교는 haystack 포인터가 증가되었습니다 그래서 첫 번째 위치를 확인하지 않은 것입니다. – DaveB

7

당신이 그것을 할 수있는 시스템에있는 경우 당신은 memmem을 사용할 수 있습니다 , 리눅스처럼 (그것은 GNU 확장이다). strstr과 같지만 바이트에서 작동하고 널 (null)로 끝나는 문자열을 검사하지 않기 때문에 두 문자열의 길이가 필요합니다.

#include <string.h> 

void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen); 
관련 문제