Sie können dies tun, indem Sie die codecvt_utf8_utf16
members directly verwenden. Der erste Schritt besteht darin, die Länge der Eingabe mit strlen
zu finden (vorausgesetzt, es ist NUL beendet). codecvt
Mitglieder arbeiten aus Bereichen, so müssen Sie wissen, wie groß Ihre Eingabe ist.
Es tritt jedoch ein Problem auf: die Länge des Ausgabepuffers. Während codecvt
über ein length
Mitglied verfügt, berechnet es nur die Länge für Konvertierungen, die in
verwenden. Das heißt, Konvertierungen von UTF-8 zu UTF-16. Es gibt keine Längenmethode für die andere Konvertierung.
Daher ist die einzige Möglichkeit, dies zu handhaben, einige der Daten in einen Puffer bekannter Größe zu konvertieren. Wenn die Konvertierung nicht vollständig abgeschlossen ist, konvertieren Sie weitere Daten. Nach all dem, was du getan hast, lege alle Teile in einen Puffer, jetzt wo du weißt, wie viele Charaktere dort sein werden.
Während Ihre Frage sagt, dass Sie nicht wollen, Strings verwenden, werde ich vector<T>
dafür verwenden, weil, wenn ich nicht, ich habe gerade vector
Umschreiben sein würde. Und dafür gibt es keinen Grund.
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;
}
Der andere Code funktioniert auf die gleiche Art und Weise, mit der Ausnahme, dass in
wird out
und die char16_t
's und char
' s vertauscht.
Die Größe Informationen verloren gehen mit Zeigern, so können Sie nicht. –
Warum möchten Sie keine String-Klassen verwenden? Dies wird zu einem Kinderspiel, indem Sie 'std :: wstring_convert' verwenden, um die Konvertierung zu erleichtern, und Sie können Literale und Arrays als Eingabe übergeben. Die Verwendung von 'std :: string' und' std :: u16string' ist einfacher als die Verwendung von 'std :: unique_ptr'-Arrays. Zumindest, wenn Sie ein 'std :: unique_ptr'-Array zurückgeben müssen, können Sie' std :: wstring_convert' für die Konvertierung verwenden und dann die resultierenden Zeichenfolgen in ein Ausgabe-Array kopieren. Die Array-Größe entspricht der Zeichenfolgengröße. –
@RemyLebeau Ich benutze benutzerdefinierte Container (Strings, Vektoren usw., die nicht STL sind) aufgrund der hohen Anforderungen an die Speicherverwaltung wie Stateful Allokatoren. –