这就是我的做法,通过将所有内容移动到不同的功能中来简化一切。未经测试,但希望它能给你一个想法。
/**
* 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);
}
来自 cmets
get_substr_impl 方法中有 2 个 const ......
故意的。
// 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;
我不会从 main 方法调用 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);)