如何将wstring转换为字节向量

3

你好,我有几个typedef:

typedef unsigned char Byte;
typedef std::vector<Byte> ByteVector;
typedef std::wstring String;

我需要将String转换为ByteVector,我尝试了以下代码:
String str = L"123";
ByteVector vect(str.begin(), str.end());

作为结果,vector 包含3个元素:1、2、3。然而,它是一个wstring,因此该字符串中的每个字符都是宽字符,所以我的期望结果应该是:0、1、0、2、0、3。
有没有标准的方法可以做到这一点,还是我需要编写一些自定义函数。

1
嗯。您可以将任何对象指针转换为char*并通过它访问字节(但不能保证对其进行解释),而且unsigned char需要具有与char相同的大小和对齐要求。因此,您可以合法地执行vect((Byte*)str.data(), ((Byte*)str.data())+(sizeof(wchar_t)*str.size()));。虽然我不会称之为“好主意”。 - BoBTFish
1
恐怕您无法使用常规迭代器完成此操作。下一个问题是字节向量中所需的字节顺序。如果您只需要机器字节顺序,可以在初始化向量之前,在迭代器上(或data()返回的指针上)使用reinterpret_cast< const unsigned char* >。如果您需要特定字节顺序,则必须自己进行转换。 - Medinoc
@jrok,我不喜欢玩得太靠近未定义的行为。我也没有说这一定是一个坏主意。只是我不想写它。 - BoBTFish
1
@BoBTFish:破坏常量正确性是邪恶的(string::data()返回一个const指针)。这就是为什么C风格的转换是不好的,我的朋友们。 - Medinoc
@Medinoc 这就是为什么这是一条评论来建议一个想法,而不是一个完整的答案。 - BoBTFish
显示剩余2条评论
2个回答

4
Byte const* p = reinterpret_cast<Byte const*>(&str[0]);
std::size_t size = str.size() * sizeof(str.front());
ByteVector vect(p, p+size);

这段代码无法编译。出现了'reinterpret_cast' : cannot convert from 'const wchar_t *' to 'Byte *'的错误。 - ST3
@user2623967,抱歉,现在可以试试了。 - jrok
2
请注意,它不一定会产生预期的输出:0, 1, 0, 2, 0, 3,因为它取决于机器的字节序。在其他机器上可能会产生 1, 0, 2, 0, 3, 0 的结果。 - Nawaz
你选择使用 Byte const* 而不是 const Byte* 有点奇怪,后者表示指向的内容是常量(而不是指针本身),这是更常见的用法。此外,str->data()&str[0] 更优雅。 - mallwright
1
@mallwright T const*const T* 是同一件事,你可能在想的是 T* const。我同意关于data()的看法,但那只出现在C++11中,并不是每个人在2013年都在使用它 - 或者当时我还不知道 :) - jrok

2

你的实际目标是什么?如果你只想获取代表对象的字节,一个相当简单的转换就可以做到,尽管我不会只使用强制转换为< unsigned char const* >,而是使用显式转换。

另一方面,如果你真正想将转换为使用UTF8或UTF16编码的序列,这通常是处理字符时所需的,那么用于编码的转换变得更加复杂。可能最简单的方法是使用C的< wcstombs() >进行转换:

std::vector<char> target(source.size() * 4);
size_t n = wcstombs(&target[0], &source[0], target.size());

上面的片段假设source不为空,并且source中的最后一个是()。该转换使用C的全局语言环境,并假定转换为设置在那里的任何字符编码。还有一个版本wcstombs_l(),您可以在其中指定语言环境。
C ++具有类似的功能,但在std::codecvt <...> facet中使用起来要困难一些。如果需要,我可以提供一个示例。

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