您可以通過使用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)。 –