This is how I would do it, which is simplify everything by moving it into different functions. Untested but it should hopefully give you an idea.
/**
* Checks if one string starts with another string. This returns an
* incorrect result if it is called where prefix is an empty string.
*/
bool starts_with_impl(const char* haystack, const char* prefix) {
if ( *prefix == 0 ){
//reached the end of prefix without having found a difference in characters
return true;
}else if ( *haystack == 0 || *prefix != *haystack ){
//either prefix is longer than haystack or there is a difference in characters.
return false;
}
//move along the haystack and prefix by one character
return starts_with_impl(++haystack, ++prefix);
}
/**
* Wrapper around starts_with_impl that returns false if prefix is an empty string
*/
bool starts_with(const char* haystack, const char* prefix) {
return *prefix ? starts_with_impl(haystack, prefix) : false;
}
int get_substr_impl(const char* haystack, const char* const needle, int index) {
if ( *haystack == 0 ){
//reached the end of haystack with no match, -1 is no string found
return -1;
}else if ( starts_with(haystack, needle) ){
//we have found a substring match.
return index;
}
//move along haystack by one character
return get_substr_impl(++haystack, needle, ++index);
}
/**
* Wrapper function for the above to hide the fact we need an additional argument.
* I am avoiding using a default argument as it makes a messy api
*/
int get_substr(const char* haystack, const char* const needle) {
return get_substr_impl(haystack, needle, 0);
}
From the comments
you've got 2 const's in the get_substr_impl method....
Intentional.
// means that the data is constant, in other words I can't change the value of needle
const char* needle;
//means that as well as the data being constant
//I can't change the address that the pointer points to.
const char* const needle;
from the main method wouldn't i just call teh get_substr_impl with the same prameters given in get_substr?
I split it as get_substr_impl
has an additional (required) argument int index
that is required for the inner workings of the function and should always start at 0. While you could call get_substr_impl("abc", "a", 0);
, it looks nicer and is more understandable to call get_substr("abc", "a");
and it avoids errors (like calling get_substr_impl("abc", "a", 1);
)