memmem() help

Hi !
My C program has this line;

char * p = memmem (buffer FileLen, bytes, 4);

I'm trying to use memmem () but I get the error;
[Error] 'memmem' was not declared in this scope.
I'm using this libs; stdio.h, stdlib.h and string.h
How to solve it?

Thanks.
That is not a standard C or C++ function defined in any standard.
Variations of it have been around forever, though. It has the advantage that it can find stuff with zeroes in it.

Unfortunately, most variations are broken in some way. You should definitely avoid this function.

Instead, write your own. This looks a little daunting, I know, but it is actually a very naïve implementation. Searching really large pieces of text can be done much more quickly, but requires quite a bit more effort to set up.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <stdio.h>
#include <string.h>

const void *memmem(
  const void *haystack, size_t haystacklen, 
  const void *needle,   size_t needlelen )
{
  // Sanity check
  if (needlelen > haystacklen) return NULL;

  // Void is useless -- we must treat our data as bytes (== unsigned chars)
  typedef const unsigned char* p;

  // We'll stop searching at the last possible position for a match, 
  // which is haystack[ haystacklen - needlelen + 1 ]
  haystacklen -= needlelen - 1;

  while (haystacklen)
  {
    // Find the first byte in a potential match
    p z = memchr( (p)haystack, *(p)needle, haystacklen );
    if (!z) return NULL;

    // Is there enough space for there to actually be a match?
    ptrdiff_t delta = z - (p)haystack;
    ptrdiff_t remaining = (ptrdiff_t)haystacklen - delta;
    if (remaining < 1) return NULL;

    // Advance our pointer and update the amount of haystack remaining
    haystacklen -= delta;
    haystack = z;

    // Did we find a match?
    if (!memcmp( haystack, needle, needlelen )) return haystack;
    
    // Ready for next loop
    haystack = (p)haystack + 1;
    haystacklen -= 1;
  }
  return NULL;
}

int main()
{
  /* http://www.randomtext.me/#/lorem/p-5/20-35 */
  const char* haystack =
  "Lorem ipsum ante nostra cras pretium suscipit dictumst curabitur aptent justo pretium molestie cubilia mi cubilia neque risus nisl tortor convallis iaculis, eros vivamus suscipit elit elementum conubia. "
  "Nullam eros vehicula aliquam ad fringilla euismod ut semper malesuada a, class elit condimentum tempus faucibus nibh sodales leo tellus, diam malesuada tincidunt sodales rhoncus ornare rutrum habitasse nisl fermentum sed massa mauris duis rutrum. "
  "Torquent mollis inceptos mollis accumsan nisl consequat lorem tincidunt, at donec curabitur duis etiam consectetur id vel, class ultricies platea arcu venenatis luctus diam. "
  "Dictumst velit viverra maecenas ante diam quis tortor nostra per at libero, turpis mollis diam varius scelerisque faucibus donec consectetur pulvinar lobortis non dapibus, mauris dictum faucibus nulla mi rhoncus quis feugiat et mi. "
  "Odio egestas potenti curabitur massa lorem nulla hac justo posuere, urna mauris aliquam primis quisque aliquam conubia fringilla, habitasse vitae euismod tempus curae vestibulum nisl lectus. ";
  
  char needle[ 1000 ];
  const char* found;
  size_t needlelen;
  
  printf( "Haystack:\n%s\n", haystack );
  
  printf( "\nEnter a needle: " );
  fflush( stdout );
  do fgets( needle, 1000, stdin );
  while (needle[ strlen( needle ) - 1 ] != '\n');
  needlelen = strlen( needle ) - 1;
  needle[ needlelen ] = '\0';
  
  found = memmem( haystack, strlen( haystack ), needle, needlelen );
  
  if (found)
    printf( "Found at position %u\n", (unsigned char*)found - (unsigned char*)haystack );
  else
    puts( "Not found." );
    
  return 0;
}

This will work fine for smallish blocks of memory. For something significantly better (if you are searching large blocks of memory), check out these guys' Boyer-Moore-Horspool implementation:
http://old.blog.phusion.nl/2010/12/06/efficient-substring-searching/

Hope this helps.
Hi ! Thanks for replies.

LB, Now I know that not part of the standard!

Duonas, old.blog .... it gave me an idea of how to implement this research.

I tried to compile your code but I am getting this error;

Compiling single file ...
--------
- Filename: C: \ Test \ Plus.cpp
- Compiler Name: TDM-GCC 4.9.2 64-bit Release

Processing C ++ source file ...

C: \ Test \ Plus.cpp: In function 'const void * memmem (const void *, size_t, const void *, size_t)':

C: \ Test \ Plus.cpp: 21: 56: error: invalid conversion from 'void *' to 'p {aka const unsigned char *}' [-fpermissive]
memchr pz = ((p) haystack, * (P) needle, haystacklen);
^

C: \ Test \ Plus.cpp: In function 'int main ()':

C: \ Test \ Plus.cpp: 66: 67: error: invalid conversion from 'const void *' to 'const char *' [-fpermissive]
found = memmem (haystack, strlen (haystack), needle, needlelen);
^


What is the correct way to compile ?

thanks.
I believe that Duonas Duoas expected you to be compiling your program as a C program, not a C++ program. If you're using C++, you can just use the algorithms library and completely avoid writing C-like code.
C is a bit more permissive than C++ when converting between void* and other pointer types. In C++, you have to add an explicit cast.

p z = (p)memchr( haystack, *(p)needle, haystacklen );

found = (const char*)memmem( (void*)haystack, strlen( haystack ), (void*)needle, needlelen );
Last edited on
Justs to say thanks ! Solved.

Another good site... Help me alot.
http://dns.uls.cl/~ej/daa_08/Algoritmos/books/book5/chap10.htm

[ ] ´s Naldo.

Topic archived. No new replies allowed.