字符指针访问

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 &)