0

I need a function like memchr() but it should be able to locate a substring(string), not an only single char. And it should return the first occurrence found in string.

For example

p1 = afunclikememchr(str1,"here the function that can locate this substring",200);

To the mods: I added the C++ tag because this is also relevant to C++

In a nutshell: I want a function that would be called memstr(), conventionally.

In addition, I must use C standard libraries, not C++, and the function should not stop when it founds a '\0' byte.

  • 2
    Would strstr work for you? http://linux.die.net/man/3/strstr – dbeer Sep 27 '13 at 18:04
  • 3
    What's wrong with [strstr](http://en.cppreference.com/w/c/string/byte/strstr) ? – P0W Sep 27 '13 at 18:04
  • std::search does what you want. – john Sep 27 '13 at 18:05
  • I considered strstr() but it stops whenever it founds a '\0' –  Sep 27 '13 at 18:06
  • 1
    This isn't *relevant* to C++ at all and the fact that you only want to use the C library doesn't help your case. – Rapptz Sep 27 '13 at 18:13
  • 2
    "I must use C standard libraries not C++", "I added the C++ tag because this is also relevant to C++". Contradiction much? – Borgleader Sep 27 '13 at 18:14
  • Using `memcmp()` it should be easy and could be fun to roll your own. – alk Sep 27 '13 at 18:58
  • Gnu has the `memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen);` extension, which does not require either of the strings to be NUL terminated. If *one* of them is NUL terminated: `strlen()` is your friend. – wildplasser Sep 27 '13 at 20:09

3 Answers3

0

Have you considered strstr()?

http://pubs.opengroup.org/onlinepubs/009695399/functions/strstr.html

The strstr() function shall locate the first occurrence in the string pointed to by s1 of the sequence of bytes (excluding the terminating null byte) in the string pointed to by s2.

pburka
  • 1,434
  • 9
  • 12
  • Yes but it stops whenever it founds a '\0' –  Sep 27 '13 at 18:06
  • If there is a `\0` _in it_ it is **not a string**, by definition. A string terminates at (just before) the first `\0` Maybe you should rephrase your questio a bit? (there is no `\0` in the example string) – wildplasser Sep 27 '13 at 20:06
0

Since you tagged this question with both c and c++ (which is wrong), I'm exploiting this fact to answer it as if it was a C question (I don't know if it really is):

So you are looking for something like memstr() which is not a standard function, but I have an implementation here.

Or just use the GNU extension memmem(), if available and you don't mind being non-standard.

Community
  • 1
  • 1
  • Thanks for answer I added this because you can use C libraries in C++ projects. –  Sep 27 '13 at 18:13
  • But is there any other methods comes with ANSI C ? –  Sep 27 '13 at 18:14
  • But strlen stops if I have '\0' in substring size_t needlesize = strlen(needle); Consider this: Substring: const char pattern[35] = {0x73,0x00,0x65,0x00,0x6E,0x00,0x64,0x00,0x75,0x00,0x73,0x00,0x65,0x00,0x72,0x00,0x6E,0x00,0x61,0x00,0x6D,0x00,0x65}; –  Sep 27 '13 at 18:31
  • @user2400925 I suggest you look up the meaning of the words "haystack" and "needle" in a dictionary. Then you will get it. I have understood your question, and my `memstr()` function does exactly what you want. You just have to call it properly. –  Sep 27 '13 at 18:32
  • Ok I will try to do. But do you have any explasion or thoughts about why the creators of C libraries did not added this simple function? I think it is as simple as strstr() –  Sep 27 '13 at 18:38
  • @user2400925: `strXXx` functions work on C-strings only -- zero terminated. `memXXx` functions work on raw bytes. Your requirement falls between them, and is unlikely to come up on a regular basis. Use `memchr` to locate a possible first character inside a range (minus the search atring length), then use `strcmp` to check it's a match. – Jongware Sep 27 '13 at 19:15
  • @user2400925 Honestly, I have no idea, and that question is out of scope (off-topic) here anyway. –  Sep 27 '13 at 19:21
0

You need the equivalent of strstr which will work on general arrays. This is what I assume from your question. There is no memstr as you probably have found so you will have to write your own.

Something like this:

size_t memstr(const unsigned char* arr, size_t length, const unsigned char* tofind, size_t flength) {
   for(size_t i = 0; i < length-flength; ++i) {
      if(memcmp(arr+i, tofind, flength) == 0)
         return i;
   }

   return -1;  //highest possible unsigned value - eg std::string::npos often implemented like this.
}


int main() {
   const unsigned char arr1[] = {1,2,3,4,5,6,7,8,9,0,3,3,3,3,4,4,4,4,4};
   size_t sz = sizeof(arr1) / sizeof(arr1[0]);
   const unsigned char fnd[] = {3,3,3};

   size_t where = memstr(arr1, sz, fnd, 3);
   return 0;
}
Angus Comber
  • 9,316
  • 14
  • 59
  • 107