您可以通过使用codecvt_utf8_utf16
members directly做到这一点。你的第一步是用strlen
找到输入的长度(假设它是NUL终止的)。 codecvt
成员的工作范围,所以你需要知道你的输入有多大。
但是,出现了一个问题:输出缓冲区的长度。虽然codecvt
确实有length
成员,但它只会使用in
计算转换的长度。也就是说,从UTF-8到UTF-16的转换。没有进行其他转换的长度方法。
因此,处理这个问题的唯一方法是将一些数据转换为已知大小的缓冲区。如果转换未完全完成,则转换更多的数据。完成所有工作后,现在将所有作品放入缓冲区,以便知道将会有多少个角色出现。
虽然你的问题说,你不想使用字符串,我将使用vector<T>
,因为如果我没有,我只是重写vector
。没有理由这样做。
std::unique_ptr<char16_t[]> ToUTF16(const char* utf8String)
{
auto end_ptr = utf8String + std::char_traits<char>::length(utf8String);
std::codecvt_utf8_utf16<char16_t> converter;
std::codecvt_utf8_utf16<char16_t>::state_type state;
std::array<char16_t, buffer_size> buffer;
std::vector<char16_t> storage;
auto curr_in_ptr = utf8String;
auto out_loc = buffer.begin();
do
{
std::codecvt_base::result rslt = converter.in(state,
curr_in_ptr, end_ptr, curr_in_ptr,
buffer.begin(), buffer.end(), out_loc);
storage.insert(storage.end(), buffer.begin(), out_loc);
}
while(curr_in_ptr != end_ptr);
//+1 for NUL terminator.
std::unique_ptr<char16_t[]> ret(new char16_t[storage.size() + 1]);
std::copy(storage.begin(), storage.end(), ret.get());
ret.get()[storage.size()] = char16_t();
return ret;
}
其他代码工作以同样的方式,除了in
变得out
和char16_t
的和char
的进行交换。
尺寸信息因指针而丢失,所以你不能。 –
为什么你不想使用字符串类?这样做可以毫不费力地使用'std :: wstring_convert'来促进转换,并且可以将文字和数组作为输入传递给它。使用'std :: string'和'std :: u16string'比使用'std :: unique_ptr'数组更容易。至少,如果您必须返回一个'std :: unique_ptr'数组,您可以使用'std :: wstring_convert'进行转换,然后将结果字符串复制到输出数组中。数组大小将是字符串大小。 –
@RemyLebeau由于强大的内存管理需求(如有状态分配器),我使用自定义容器(字符串,向量等不是stl)。 –