【发布时间】:2013-05-30 07:55:16
【问题描述】:
由于必须将一些数据传递给相当过时的 API,我正在尝试将 std::string 转换为 char*(复制而不是强制转换)。
从表面上看,有很多方法可以做到这一点,但有人建议我将其作为一个似乎明智的矢量来做。但是,当我尝试这样做时,结果是乱码。代码如下:
const string rawStr("My dog has no nose.");
vector<char> str(rawStr.begin(), rawStr.end());
cout << "\"" << (char*)(&str) << "\"" << endl;
(请注意令人不快的 C 转换 - 使用 static_cast 不起作用,这可能告诉我一些事情)
当我运行它时,我得到:
"P/"
显然不对。我看了一下gdb中的向量
(gdb) print str
$1 = std::vector of length 19, capacity 19 = {77 'M', 121 'y', 32 ' ', 100 'd', 111 'o',
103 'g', 32 ' ', 104 'h', 97 'a', 115 's', 32 ' ', 110 'n', 111 'o', 32 ' ', 110 'n',
111 'o', 115 's', 101 'e', 46 '.'}
虽然结尾没有空终止符,但看起来是正确的,这令人担忧。向量 (sizeof(str)) 的大小为 24,这表明字符存储为 8 位。
我哪里出错了?
【问题讨论】:
-
如果你使用 C++11,传递
&rawStr[0]没问题,只要它只写到 null 之前。 -
字符串不包含作为
begin()到end()范围内的元素的空终止符。其次,向量的地址不是向量数据的第一个元素的地址。 -
@chris:
[citation needed](标准中关于这个问题的措辞非常微妙和古怪,但据我所知,这不能保证是空终止的 -
@jalf,我相信这与
data()与 C++11 中的c_str()相同。如果你有兴趣,已经有一个question关于这个主题。 -
@chris 当然,它们是相同的,但它们都不与
&rawStr[0]相同(并且该问题的答案仅表明内部字符串将在您使用时以空值结尾已经调用了c_str()或data()。不能保证它会总是为空终止。