elv*_*ide 3 c++ unicode utf-8 utf-16 c++11
如何在不使用任何字符串类(例如or但仅使用纯数组和文字字符串)的情况下std::codecvt_utf8_utf16从 uft8 转换为 utf16 并返回?我如何知道存储转换所需的缓冲区的正确大小?std::stringstd::wstring
比如满足这个接口:
std::unique_ptr<char16_t[]> ToUTF16(const char* utf8String);
std::unique_ptr<char[]> ToUTF8(const char16_t* utf16String);
Run Code Online (Sandbox Code Playgroud)
您可以codecvt_utf8_utf16直接使用成员来完成此操作。第一步是找到输入的长度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;
}
Run Code Online (Sandbox Code Playgroud)
其他代码以相同的方式工作,除了in变为out,并且char16_t和char被交换。