字符指针访问
Character pointer access
我想访问第 ith 个元素的字符指针。下面是示例代码
string a_value = "abcd";
char *char_p=const_cast<char *>(a_value.c_str());
if(char_p[2] == 'b') //Is this safe to use across all platform?
{
//do soemthing
}
提前致谢
在这种情况下,您可以将 char* 视为字符数组(C 字符串)。允许使用括号。
指针类型允许使用数组访问器 []
,如果 []
内的偏移指的是有效内存,则会导致定义的和可预测的行为。
const char* ptr = str.c_str();
if (ptr[2] == '2') {
...
}
在所有平台上都是正确的如果 str
的长度为 3 个字符或更多。
一般来说,如果您不改变正在查看的 char*
,最好避免使用 const_cast
而使用 const char*
。另请注意,std::string
提供 operator[]
,这意味着您无需在 str
上调用 .c_str()
即可对其进行索引并查看 char
.如果 str
的长度为 3 个字符或更多,这在所有平台上同样是正确的 。如果事先不知道字符串的长度,使用std::string::at(size_t pos)
,它执行绑定检查,如果检查失败则抛出out_of_range
异常。
问题本质上是关于安全地查询字符串中的字符。
const char* a = a_value.c_str();
是安全的,除非其他一些操作修改了它后面的字符串。如果您可以保证在使用 a 之前没有其他代码执行修改,那么您已经安全地检索到指向以 null 结尾的字符串的指针。
char* a = const_cast<char *>(a_value.c_str());
从来都不安全。您已经生成了一个指向可写内存的指针。但是,该内存从未设计为可写入。不能保证写入该内存实际上会修改字符串(并且实际上不能保证它不会导致核心转储)。这是未定义的行为——绝对不安全。
此处参考:http://en.cppreference.com/w/cpp/string/basic_string/c_str
寻址 a[2]
是安全的,前提是您可以证明所有可能的代码路径确保 a 代表指向长度超过 2 个字符的内存的指针。
如果您想要安全,请使用:
auto ch = a_string.at(2); // will throw an exception if a_string is too short.
或
if (a_string.length() > 2) {
auto ch = a_string[2];
}
else {
// do something else
}
您可以使用 operator[]()
访问 std::string
中的第 i 个元素,如下所示:
std::string a_value = "abcd";
if (a_value[2] == 'b')
{
// do stuff
}
如果您使用符合 C++11 的 std::string
实现,您还可以使用:
std::string a_value = "abcd";
char const * p = &a_value[0];
// or char const * p = a_value.data();
// or char const * p = a_value.c_str();
// or char * p = &a_value[0];
21.4.1/5
The char-like objects in a basic_string object shall be stored contiguously.
21.4.7.1/1: c_str() / data()
Returns: A pointer p such that p + i == &operator[](i)
for each i in [0,size()].
大多数人都很好地解释了它是如何安全的,但如果可以的话,我想扩展一下。
由于您使用的是 C++,并且您使用的是字符串,因此您可以简单地执行以下操作来访问一个字符(您不会遇到任何麻烦,而且您仍然不必处理cpp 中的 cstrings :
std::string a_value = "abcd";
std::cout << a_value.at(2);
在我看来,这是一个更好的选择,而不是绕道而行。
string::at 将 return 一个 char & 或一个 const char& 取决于你的字符串对象。 (在这种情况下,const char &)
我想访问第 ith 个元素的字符指针。下面是示例代码
string a_value = "abcd";
char *char_p=const_cast<char *>(a_value.c_str());
if(char_p[2] == 'b') //Is this safe to use across all platform?
{
//do soemthing
}
提前致谢
在这种情况下,您可以将 char* 视为字符数组(C 字符串)。允许使用括号。
指针类型允许使用数组访问器 []
,如果 []
内的偏移指的是有效内存,则会导致定义的和可预测的行为。
const char* ptr = str.c_str();
if (ptr[2] == '2') {
...
}
在所有平台上都是正确的如果 str
的长度为 3 个字符或更多。
一般来说,如果您不改变正在查看的 char*
,最好避免使用 const_cast
而使用 const char*
。另请注意,std::string
提供 operator[]
,这意味着您无需在 str
上调用 .c_str()
即可对其进行索引并查看 char
.如果 str
的长度为 3 个字符或更多,这在所有平台上同样是正确的 。如果事先不知道字符串的长度,使用std::string::at(size_t pos)
,它执行绑定检查,如果检查失败则抛出out_of_range
异常。
问题本质上是关于安全地查询字符串中的字符。
const char* a = a_value.c_str();
是安全的,除非其他一些操作修改了它后面的字符串。如果您可以保证在使用 a 之前没有其他代码执行修改,那么您已经安全地检索到指向以 null 结尾的字符串的指针。
char* a = const_cast<char *>(a_value.c_str());
从来都不安全。您已经生成了一个指向可写内存的指针。但是,该内存从未设计为可写入。不能保证写入该内存实际上会修改字符串(并且实际上不能保证它不会导致核心转储)。这是未定义的行为——绝对不安全。 此处参考:http://en.cppreference.com/w/cpp/string/basic_string/c_str
寻址 a[2]
是安全的,前提是您可以证明所有可能的代码路径确保 a 代表指向长度超过 2 个字符的内存的指针。
如果您想要安全,请使用:
auto ch = a_string.at(2); // will throw an exception if a_string is too short.
或
if (a_string.length() > 2) {
auto ch = a_string[2];
}
else {
// do something else
}
您可以使用 operator[]()
访问 std::string
中的第 i 个元素,如下所示:
std::string a_value = "abcd";
if (a_value[2] == 'b')
{
// do stuff
}
如果您使用符合 C++11 的 std::string
实现,您还可以使用:
std::string a_value = "abcd";
char const * p = &a_value[0];
// or char const * p = a_value.data();
// or char const * p = a_value.c_str();
// or char * p = &a_value[0];
21.4.1/5
The char-like objects in a basic_string object shall be stored contiguously.
21.4.7.1/1: c_str() / data()
Returns: A pointer p such that
p + i == &operator[](i)
for each i in [0,size()].
大多数人都很好地解释了它是如何安全的,但如果可以的话,我想扩展一下。
由于您使用的是 C++,并且您使用的是字符串,因此您可以简单地执行以下操作来访问一个字符(您不会遇到任何麻烦,而且您仍然不必处理cpp 中的 cstrings :
std::string a_value = "abcd";
std::cout << a_value.at(2);
在我看来,这是一个更好的选择,而不是绕道而行。 string::at 将 return 一个 char & 或一个 const char& 取决于你的字符串对象。 (在这种情况下,const char &)