2015-05-06 65 views
-1

我想访问字符指针第i个元素。下面是示例代码预先字符指针访问

+6

'a_value [2]'有什么问题?' – Quentin

+0

为什么你n在这里eed'const_cast'? – myaut

+0

@BoBTFish它不是,只要'a_char'不用于实际修改字符串。这仍然是一个非常非常糟糕的主意。 – Quentin

回答

3

指针类型允许使用数组访问器[],并且如果[]中的偏移量指向有效内存,将导致定义的和可预测的行为。

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异常。

-1

在这种情况下,你可以把炭

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 
} 

由于*作为字符数组(C-字符串)。括号是允许的。

1

问题实质上是关于安全地查询字符串中的字符。

const char* a = a_value.c_str(); 

是安全的,除非某些其他操作修改后面的字符串。如果您可以保证在使用a之前没有其他代码执行修改,那么您已经安全地检索了一个指向以空字符结尾的字符串的指针。

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 
} 
+0

_“从来不安全”,“未定义的行为”_不正确。演员本身是完全明确的。 –

+0

@LightnessRacesinOrbit恭敬地,我相信你错误地引用了我。我传达的是,标准并不保证由c_str()产生的字符串甚至与std :: string中的存储位于同一个内存地址。它也不保证内存是可写的。因此写入它是未定义的行为。没有理由不应该导致段错误。 –

+2

OP的_not_写入它。在问题的代码中没有_inherent_非安全和没有未定义的行为。要么你正在回答其他问题,要么我没有误导你。 :) –

3

您可以在std::string访问第i个元素使用其operator[]()这样的:

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

的炭状物体在一个basic_string的对象将被连续地存储。

21.4.7.1/1:c_str()/数据()

返回:指针p,使得p + i == &operator[](i)对于每个i在[0,大小()]。

+0

a_value.c_str()不一定与&a_value [0]相同。标准的措辞很微妙,并允许两个不同的调用返回不同的内存引用/地址。 –

+0

@RichardHodges毕竟它是一样的。看我的标准报价。 'c_str()'需要返回一个指针,使得'p + 0 ==&operator [](0)'表示'a_value.c_str()==&a_value [0]'。 – Pixelchemist

+0

我明白了。我错过了。 –

0

大家都很好地解释了它的安全性,但如果没有问题,我想扩展一下。

由于您使用的是C++,而且您使用的是字符串,因此只需执行以下操作即可访问caracter(并且您不会遇到任何问题,而且您仍然不必处理cstrings在CPP:

std::string a_value = "abcd"; 
    std::cout << a_value.at(2); 

这在我看来是一个更好的选择,而不是走出去的方式 字符串::在将根据您的字符串对象返回一个char &或一个const char &(在此。 case,const char &)