Это то, как я бы это сделал, что упрощает все, перемещая его в разные функции. Не проверено, но, надеюсь, это даст вам представление.
/**
* 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);
}
Из комментариев
у вас есть 2 константы в методе get_substr_impl ....
Преднамеренное.
// 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;
из основного метода я бы не вызвал get_substr_impl с теми же параметрами, что и в get_substr?
Я разделил его, так как get_substr_impl
имеет дополнительный (обязательный) аргумент int index
, который необходим для внутренней работы функции и всегда должен начинаться с 0. Хотя вы можете вызвать get_substr_impl("abc", "a", 0);
, он выглядит лучше более понятно звонить get_substr("abc", "a");
и избегать ошибок (например, звонить get_substr_impl("abc", "a", 1);
)