[英]Translating std::string to vector<char>
由于要将一些数据传递到过时的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位。
我要去哪里错了?
std::vector
的实例本身不是字符数组-它指向一个数组。 而不是(char*)(&str)
尝试&str[0]
。
从您的gdb输出判断,您还需要在将向量传递到旧版API之前将零推入向量的末尾。
首先, std::string
不包含空终止符作为[ begin()
, end()
)覆盖范围内的元素。 其次,向量的地址不是向量数据的第一个元素的地址。 为此,您需要&str[0]
或str.data()
:
#include <vector>
#include <string>
#include <iostream>
int main()
{
const std::string rawStr("My dog has no nose.");
std::vector<char> str(rawStr.begin(), rawStr.end());
str.push_back('\0');
std::cout << "\"" << &str[0] << "\"" << std::endl;
std::cout << "\"" << str.data() << "\"" << std::endl; // C++11
}
您需要做的两件事:
1)使用&str [0]获取向量中第一个字符的地址; 这是绝对好的(如果有些人为的话),因为该标准保证了向量存储器是连续的。 您不能简单地写&str,因为那是向量的地址,不一定是第一个数据元素的地址。
2)如果您想使用类似标准c的函数将字符显示为字符串,请在向量的末尾插入一个空终止符。 在第二点上我可能是错的。 rawStr.end()是否指向与“我的狗没有鼻子”关联的隐式空终止符?
&str为您提供指向矢量对象的指针,而不是指向包含的字符串的指针。
如果希望将其打印为C字符串,则需要将0推到末尾,然后输出&str [0](它将把您的地址抓到包含的数组的开头)。
不过,这非常丑陋。 您最好创建自己的继承std :: vector的字符串向量类,或者使用经过精心设计的函数迭代向量,从字面上打印每个元素。
编辑:
如果您不熟悉C ++ 11,则可以在此处干净使用lambda的for_each:
std::for_each(str.begin(), str.end(), [](char i) -> void {std::cout << i;});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.