2011-03-15 27 views
3

使用C,我需要在可能包含空值的缓冲区中查找子字符串。如何在包含null的缓冲区中搜索子字符串?

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

我需要返回的字符串,或空的开始,similat到的strstr():

request_segment_end = mystrstr(request_segment_start, boundary); 

是否有你所知道的任何现有的实现?

更新

我发现memove的实现,取决于谷歌的于codesearch,我已经在这里逐字复制,未经检验的,

/* 
* 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 2011-03-15 08:01:59

+0

您可以实现[ESMAJ](http://www-igm.univ-mlv.fr/~lecroq/string/index.html)中描述的方法之一。 – pmg 2011-03-15 10:02:07

回答

4

对于包含空字符的“字符串”,我没有任何意义。字符串是空终止的,所以第一次出现标志着字符串的结尾。另外,什么是"nulls"之后的空终止符在它后面没有更多的字符。

如果您的意思是在缓冲区中搜索,那么这对我更有意义。你只需要搜索缓冲区忽略空字符,只依赖长度。我不知道任何现有的实现,但它应该很容易掀起一个简单的天真的实现。当然,根据需要在这里使用更好的搜索算法。

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 2011-03-15 08:49:19

+0

只是一个笔记,以清理一些其他好的答案的细节,该算法是一个线性搜索,它实际上是O(n),而不是O(n^2),我不认为你可以做得更好,除非数据您的搜索按某种方式排序。此外,我认为有一个错误,第一次比较是在干草堆指针增加之后完成的,因此不检查第一个位置。 – DaveB 2017-01-27 15:26:21

7

可以使用将memmem如果你是有它的系统上,就像linux(它是一个GNU扩展)。就像strstr一样,但对字节起作用,并且需要两个“字符串”的长度,因为它不检查以空字符结尾的字符串。

#include <string.h> 

void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen); 
相关问题