我希望我的函数能与cstring
/ string.h
库中使用的函数“ strchr”相同。
我了解我无法将“ const char *”变量/数组强制转换为“ char *”。但是,预定义的“ strchr”函数如何能够同时传递“ const char”和“ char”数据类型数组并正常工作?我该如何更改我的它,使其也起作用?
char* my_strchr(char *place_to_find, char what_to_find)
{
for(int i=0;place_to_find[i];i++)
if(what_to_find==place_to_find[i]) return place_to_find+i;
return NULL;
}
...
int main()
{
const char vocals1[]="AEIOUaeiou";
char vocals2[]="AEIOUaeiou";
cout<<strchr(vocals1,'e');
cout<<strchr(vocals2,'e');
cout<<my_strchr(vocals1,'e');
cout<<my_strchr(vocals2,'e');
return 0;
}
您可能已经知道,我的第三个cout<<
无法正常工作。
我正在寻找一种更改功能的方法(我猜第一个参数应该以某种方式进行类型转换)。
答案 0 :(得分:2)
如何使我的strchr函数同时使用'const char'和'char'数组作为第一个参数?
您可以将参数更改为const char*
。这样可以将两个指针都传递到char
和const char
。
但是,您将返回一个非常量指针指向该数组,如果指针指向常量数组则不应该这样做。因此,在传递const char*
时,您的函数还应该返回const char*
但是,预定义的“ strchr”函数如何能够同时传递“ const char”和“ char”数据类型数组并正常工作?
有两个预定义的std::strchr
函数。一个接受并返回char*
的对象,另一个接受并返回const char*
的对象:
const char* strchr(const char* str, int ch);
char* strchr( char* str, int ch);
如果希望在char*
参数的情况下返回char*
,则每种情况都需要具有不同的函数,就像标准库一样。您可以像标准库一样使用重载,也可以使用函数模板来生成两个变体而无需重复:
template<class Char>
Char* my_strchr(Char *place_to_find, char what_to_find)
请注意,该函数的C版本声明为char *strchr(const char *str, int ch)
。这使得单个函数在两种情况下都可用,但不安全,因为即使将const数组作为参数传递,类型系统也无法阻止函数的用户通过返回的非const指针进行修改。
答案 1 :(得分:0)
简短的答案:将place_to_find const char *类型设为
发生错误的原因是,您不能隐式将指向const char的指针转换为指向非const char的指针。如果可以的话,可以更改指针指向的字符,这将使实现const char类型的目的摆在首位。
您可以隐式地将指向非const char的指针转换为指向const char的指针,因为它不会消除任何限制。
L.E .:而且,返回值应该是const char *,因为如果您不这样做,它将再次删除不允许的const限制。唯一的问题是您将无法通过返回的指针修改数组。如果还需要这样做,则必须在char和const char上都重载该方法。
答案 2 :(得分:0)
使用C ++标准库中的方法进行两次重载:
char* my_strchr( char *place_to_find, char what_to_find)
const char* my_strchr(const char *place_to_find, char what_to_find)
即使在您的情况下,仅第二个重载就足够了(demo),当您需要找到一个字符然后替换它时,您将无法支持重要的用例:
// This would not work with only one overload:
char *ptr = my_strchr(vocals2,'e');
if (ptr) {
*ptr = 'E';
}
这就是为什么非const
超载是必要的原因。
注意:我假设您是在进行学习,因为C风格的字符串函数已不再被std::string
功能所取代。 / p>