函数char* strrchr(const char *str, int ch)
在char*
(str
)中返回const char *
最后一次出现的指针(ch
)。
所以我们可以编写以下代码而不进行任何演员:
#include <string.h>
int main()
{
const char CONSTSTR[] = "foo/bar/foobar.txt";
char *ptr = strrchr (CONSTSTR, '/');
*ptr++ = 'B';
*ptr++ = 'A';
*ptr++ = 'D';
}
返回char*
代替const char*
有什么好处?
编辑:
正如Shafik Yaghmour指出的那样,How does strchr implementation work?
由于我的代码是用C ++编写的,我将使用<cstring>
代替<string.h>
。谢谢你的回答; - )
然而,Mike Seymour's answer最适合这个问题。我甚至添加了a more detailed answer below来清楚地说明strrchr()
是一个C函数(不允许重载),该声明适用于 const 和非const 字符串。因为可以使用非const 字符串调用strrchr()
,所以返回的字符串也应该是非const 。
答案 0 :(得分:13)
您正在查看C标准库(<string.h>
)中的遗留函数。 C ++库(<cstring>
)引入了appropriate const
and non-const
overloads,因此您应该尽可能使用它。
答案 1 :(得分:6)
在C中,函数必须像这样,或强迫用户在许多情况下使用狡猾的强制转换:
const
指针,则无法搜索const
字符串; const
指针,则无法使用它来修改非const
字符串。在C ++中,您应该包含<cstring>
而不是已弃用的仅限C的标头。这将为您提供两个const-correct重载,无法在C中完成:
const char* strchr(const char* s, int c);
char* strchr( char* s, int c);
答案 2 :(得分:3)
const char *str
表示strrchr
保证不修改str
。
返回const char *
表示strrchr
禁止修改返回的值。
答案 3 :(得分:2)
strrchr()
from <string.h>
是一个C函数。由于C不允许函数重载,strrchr()
被设计为适合 const 和非const 字符串。
char* strrchr( const char *str, int ch );
可以使用非const 字符串调用 strrchr()
,因此返回的字符串也应该是非const ,如以下示例中所述。
const 上下文没有编译错误:
#include <string.h>
int main()
{
const char CONSTSTR[] = "foo/bar/foobar.txt";
const char *basename = strrchr (CONSTSTR, '/');
// basename points to "foobar.txt"
}
非const 上下文,没有编译错误:
#include <string.h>
int main()
{
char nonconst[] = "foo/bar/foobar.txt";
char *basename = strrchr (nonconst, '/');
basename[0] = 'G';
basename[3] = 'D';
// basename points to "GooDar.txt"
}
错误使用也没有编译错误:
#include <string.h>
int main()
{
const char CONSTSTR[] = "foo/bar/foobar.txt";
char *nonconst = strrchr (CONSTSTR, '/');
*nonconst++ = 'B';
*nonconst++ = 'A'; // drawback of the unique declaration:
*nonconst++ = 'D'; // no compilation error
}
const char* strrchr( const char* str, int ch ); //1st
char* strrchr( char* str, int ch ); //2nd
const 上下文使用第一个:
#include <cstring>
int main()
{
const char CONSTSTR[] = "foo/bar/foobar.txt";
const char *basename = std::strrchr (CONSTSTR, '/');
// basename points to "foobar.txt"
}
非const 上下文使用第二个:
#include <cstring>
int main()
{
char nonconst[] = "foo/bar/foobar.txt";
char *basename = std::strrchr (nonconst, '/');
basename[0] = 'G';
basename[3] = 'D';
// basename points to "GooDar.txt"
}
错误的用法应该产生编译错误:
#include <cstring>
int main()
{
const char CONSTSTR[] = "foo/bar/foobar.txt";
char *nonconst = std::strrchr (CONSTSTR, '/');
// Visual C++ v10 (2010)
// error C2440: 'initializing' : cannot convert from 'const char *' to 'char *'
*nonconst++ = 'B';
*nonconst++ = 'A';
*nonconst++ = 'D';
}
但是最后一个示例使用g++ -Wall file.cpp
不会产生任何编译错误。使用GCC版本 4.1.2(RedHat)和 4.7.2(MinGW)进行测试。
答案 4 :(得分:0)
为什么要禁止代码修改返回的变量?请注意const char *
不是char * const
,你可以在任何情况下修改角色,但是你无法控制返回的值本身,这没有多大意义,因为你可以想要更改它并根据您的目的在不同的位置编辑基础字符串。