我注意到memmem
在Windows的MSVC中不可用,因此我尝试为其编写一些内容。我有以下代码:
void *memmem(const void *haystack_start, size_t haystack_len, const void *needle_start, size_t needle_len)
{
const unsigned char *haystack = (const unsigned char *)haystack_start;
const unsigned char *needle = (const unsigned char *)needle_start;
const unsigned char *h = NULL;
const unsigned char *n = NULL;
size_t x = needle_len;
/* The first occurrence of the empty string is deemed to occur at
the beginning of the string. */
if (needle_len == 0) {
return (void *)haystack_start;
}
/* Sanity check, otherwise the loop might search through the whole
memory. */
if (haystack_len < needle_len) {
return NULL;
}
for (; *haystack && haystack_len--; haystack++) {
x = needle_len;
n = needle;
h = haystack;
if (haystack_len < needle_len)
break;
if ((*haystack != *needle) || (*haystack + needle_len != *needle + needle_len))
continue;
for (; x; h++, n++) {
x--;
if (*h != *n)
break;
if (x == 0)
return (void *)haystack;
}
}
return NULL;
}
但是,我认为它无法正常工作。如果我尝试这样的事情:
static const char haystack[24] = {
0x4e, 0x65, 0x76, 0x65, 0x72, 0x20, 0x67, 0x6f,
0x6e, 0x6e, 0x61, 0x20, 0x67, 0x69, 0x76, 0x65,
0x20, 0x79, 0x6f, 0x75, 0x20, 0x75, 0x70, 0x2c,
};
static const char needle[8] = {
0x20, 0x79, 0x6f, 0x75, 0x20, 0x75, 0x70, 0x2c
};
char *res = memmem(haystack, sizeof(haystack), needle, sizeof(needle));
printf("%s", res);
结果为空。有什么想法可能是问题所在吗?
答案 0 :(得分:4)
我认为您过于复杂了。
void *memmem(const void *haystack, size_t haystack_len,
const void * const needle, const size_t needle_len)
{
if (haystack == NULL) return NULL; // or assert(haystack != NULL);
if (haystack_len == 0) return NULL;
if (needle == NULL) return NULL; // or assert(needle != NULL);
if (needle_len == 0) return NULL;
for (const char *h = haystack;
haystack_len >= needle_len;
++h, --haystack_len) {
if (!memcmp(h, needle, needle_len)) {
return h;
}
}
return NULL;
}
直到haystack_len大于或等于needle_len,您应该将heystack中的当前位置的针与当前内存进行比较。如果是真的,请返回heystack。
const void *
指针const unsigned char *haystack = (const unsigned char *)haystack_start;
就是const unsigned char *haystack = haystack_start;
(*haystack != *needle) || (*haystack + needle_len != *needle + needle_len))
在评论中所说的那样。一旦使用[]
运算符而不是*
:haystack[0] != needle[0] || haystack[0] + needle_len != needle[0] + needle_len
,就变得显而易见。即使您的意思是... != needle[needle_len]
,也无济于事。
for (; *haystack && haystack_len--; haystack++) {
if (haystack_len < needle_len)
break;
为什么不呢?
for (; *haystack && haystack_len < needle_len; haystack_len--, haystack++)
?
表达式*haystack
只是无效的,您没有像strstr
那样检查以空值结尾的字符串。 heystack指向内存中的任何字节,其值可以为零。 haystack_len
保持heystack的长度。
答案 1 :(得分:1)
for (; *haystack && haystack_len--; haystack++) {
在这里,您在循环开始时递减haystack_len。这意味着,当您达到匹配数haystack_len = 7但needle_len = 8时。因此,您无法通过f (haystack_len < needle_len)
检查和continue
。正如卡米尔(Kamil)在评论中指出的那样,您可能也不想在干草堆上检查一下。所以我建议
for (; haystack_len > 0; ++haystack, --haystack_len) {
答案 2 :(得分:0)
以下语句相同
char needle[] = "a test";
char needle[7] = { 'a', ' ', 't', 'e', 's', 't', '\0' };
您的haystack
与'\0'
在同一位置没有needle
。
尝试
// needle is NOT a string
char needle[6] = "a test"; // needle is NOT a string