如何将std::vector<char>转换为std::vector<wchar_t>?

7
我有一个字节的std::vector (char),我想做的就是将此向量转换为wchar_t类型的向量。显然,我需要复制数据,但这里的问题是,我已经在左侧拥有了UTF-16字节流,我只想将其移动到wchar_t向量中以便使用。理想情况下,我想交换缓冲区,但我不确定如何以安全的方式实现...那么,在C++中,如何进行高效且安全的转换复制操作呢?
注意:我会将我的UTF-16字符串存储为或>,但我有这个内存缓冲区,我碰巧知道它是UTF-16格式,我需要复制它,但不知道怎么搞...

2
什么?你把UTF-16数据存储为char?顺便说一下,从char转换为wchar_t是使用widen完成的,但我猜这不是你想要的 http://www.cplusplus.com/reference/std/locale/ctype/widen/ - Šimon Tóth
http://www.codeproject.com/Tips/196097/Converting-ANSI-to-Unicode-and-back?display=Print 可能会回答它。 - parapura rajkumar
并且扩展Let_Me_Be的评论:为什么将UTF-16数据存储为char - Griwes
不,我的做法是将文本文件加载到内存缓冲区中(具体来说,这是我的std::vector<uint8>字节序列)。然后我使用一个简单的启发式方法,查看前几个字节以确定编码方式。如果我找到了UTF-16字节顺序标记,我知道我真正需要做的就是改变我查看这些字节的方式,就可以了。最好的情况是,我希望能够在不复制整个缓冲区的情况下,将内容从内存缓冲区传输到文本缓冲区。复制并不是问题,但我正在寻找一种简单的方法来完成这个转换。 - John Leidegren
@JohnLeidegren:我一分钟后有一个会议,所以我要删除我的当前答案,直到我能给你一个更好的答案为止。 - John Dibling
显示剩余5条评论
3个回答

9
最有效(也是最明智)的方法是不去做它。让您的 vector<char> 拥有数据缓冲区,并创建一对 wchar_t 指针作为迭代器,指向向量中的位置即可。
std::vector<char> vec;
wchar_t* first = reinterpret_cast<wchar_t*>(&vec[0]);
wchar_t* last = reinterpret_cast<wchar_t*>(&vec[0] + vec.size());

现在你有一个迭代器对,可以很好地与所有标准库算法配合使用。而且你不需要复制任何字节。 :)
(免责声明:我假设向量的大小可被sizeof(wchar_t)整除。否则,您将需要调整last指针)

这很准确,然后我可以使用assign,然后它会复制这些东西,对吧?在我的想法中将其复制是可以的,我只是希望有一个交换技巧。我的意思是,std::vector的内部是相同的,我只是想要交换掉其中的内容(就像reinterpret_cast一样),但这样做也不错。 - John Leidegren
static_cast 就很好。 - Alexandre C.
@AlexandreC:我认为static_cast会导致未定义的行为。我也认为它在实践中不起作用,这取决于向量存储大小或结束指针的方式。 - Mooing Duck
@MooingDuck:static_castreinterpret_cast 更不容易出现未定义行为,并且在非函数指针之间进行转换时同样有效。 - Alexandre C.
这是否违反了严格别名规则或对齐规则? - nyanpasu64

1
std::vector<char> v1;
std::vector<wchar_t> v2;

wchar_t *begin = (wchar_t *) &v2.front();
wchar_t *end   = (wchar_t *) (&v2.back() + 1);

v1.assign(begin, end);

我没有测试过这个,但我无法想象这样的东西不会起作用...如果你有字节序问题,这将变得更加复杂。


使用&v2.back() + 1而不是end(),因为end()返回一个迭代器。令人困惑的是,它可能看起来可以工作,因为迭代器恰好是指针,但在另一个实现或使用调试版本的vector时可能会停止工作。 - Steve Jessop

1
std::vector<char> v1;
std::vector<wchar_t> v2;

const char * cv1 = v1.data();

const wchar_t * cv2 = static_cast<const wchar_t *>(cv1);
std::copy(cv2, cv2 + v1.size() / sizeof(wchar_t), std::back_inserter(v2));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接