All functions prefixed with str in the C standard library assume that you pass a null terminated string to them. If you pass something else, like in this case, you invoke undefined behavior and will get crashes or wrong results etc.
We could cook up our own (naive) function for this easily enough by iterating across the data and comparing it to the search key string with memcmp:
#include <string.h>
#include <stdint.h>
const uint8_t* memstr (const uint8_t* data, const char* key, size_t size)
{
const uint8_t* result = NULL;
size_t key_length = strlen(key);
for(size_t i=0; i<size-key_length+1; i++)
{
if(memcmp(&data[i], key, key_length) == 0)
{
result = &data[i];
break;
}
}
return result;
}
Here the requirement is that key is a null terminated string but data could be anything. Since key is a string we can call strlen on it. We should only iterate up to the buffer size minus key length amount of bytes. So for example with 8 data bytes and a search key of "000" thats 8-3=5 bytes. But we have to check data indices 0 to 5, so a +1 on the loop condition is needed.
Complete test code:
#include <string.h>
#include <stdint.h>
#include <stdio.h>
const uint8_t* memstr (const uint8_t* data, const char* key, size_t size)
{
const uint8_t* result = NULL;
size_t key_length = strlen(key);
for(size_t i=0; i<size-key_length+1; i++)
{
if(memcmp(&data[i], key, key_length) == 0)
{
result = &data[i];
break;
}
}
return result;
}
#define test_memstr(data, key) \
found = memstr(data, key, sizeof data); \
if(found) \
printf("\"%.*s\" found at index %tu\n", \
strlen(key), found, found-data); \
else \
puts("Not found");
int main (void)
{
uint8_t data1[8] = {0xcb,0xe2,0x3d,0x96,0x55,0xfc,0xcd,0x43};
uint8_t data2[11] = {0x48,0x65,0x6C,0x6C,0x6F,0x20,0x57,0x6F,0x72,0x6C,0x64};
const uint8_t* found;
test_memstr(data1, "000");
test_memstr(data2, "World");
test_memstr(data2, "Hello");
}
"000"is 4 characters, there is an additional null-terminatormemmemfunction that works with byte arrays (pointer + length) rather than NULL-terminated strings, but otherwise does the same thing asstrstr