如何在没有任何字符串类的情况下使用std :: codecvt_utf8_utf16转换为utf8和从utf8转换?

时间:2017-02-25 19:22:15

标签: c++ c++11 unicode utf-8 utf-16

如何使用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);

1 个答案:

答案 0 :(得分:4)

您可以使用codecvt_utf8_utf16 members directly执行此操作。您的第一步是使用strlen找到输入的长度(假设它已终止NUL)。 codecvt成员在范围之外工作,因此您需要知道您的输入有多大。

然而,出现了一个问题:输出缓冲区的长度。虽然codecvt确实有length成员,但它只会使用in来计算转化的长度。也就是说,从UTF-8到UTF-16的转换。没有长度方法可以进行其他转换。

因此,处理此问题的唯一方法是将一些数据转换为已知大小的缓冲区。如果转换未完全完成,则转换更多数据。完成所有操作后,将所有部分放入缓冲区,因为您知道将有多少字符存在。

虽然你的问题说你不想使用字符串,但我会使用vector<T>,因为如果我没有,我只是重写{{1} } 的。并且没有理由这样做。

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; } 变为inoutchar16_t被交换。