UTF8 aan/uit breed char conversie in STL
Is het mogelijk om te zetten in UTF8-string in een std::string std::wstring en vice versa in een platform-onafhankelijke manier? In een Windows-toepassing die ik zou gebruiken MultiByteToWideChar en WideCharToMultiByte. Echter, de code is opgesteld voor meerdere Os ‘ en ik ben beperkt tot standard C++ – bibliotheek.
- Overigens, de standaard C++ – bibliotheek is niet genoemd STL; de STL wordt slechts een klein onderafdeling van de standaard C++ – bibliotheek. In dit geval geloof ik dat je het vragen om functionaliteit in de standaard C++ – bibliotheek, en ik heb beantwoord.
- Je hebt niet aangegeven met welke codering je wilt om te eindigen met. wstring niet opgeven van een bepaalde codering. Natuurlijk zou het natuurlijk om te zetten naar utf32 op platforms waar wchar_t maxlen is 4 bytes groot, en utf16 als wchar_t maxlen is 2 bytes. Is dat wat je wilt?
Ik heb deze vraag gesteld op 5 jaar geleden. Deze draad was erg nuttig voor mij toen, kwam ik tot een conclusie, daarna verhuisde ik met mijn project. Het is grappig dat ik iets nodig had soortgelijke onlangs, geheel los van dat project uit het verleden. Als ik onderzoek deed naar mogelijke oplossingen, struikelde ik over mijn eigen vraag 🙂
De oplossing die ik koos is nu gebaseerd op C++11. De boost libraries dat Constantin vermeldt in zijn antwoord zijn nu onderdeel van de standaard. Als wij in de plaats van std::wstring met de nieuwe string type std::u16string, dan is de conversie zal er als volgt uitzien:
UTF-8 en UTF-16
UTF-16 en UTF-8
Gezien vanaf de andere antwoorden, er zijn meerdere benaderingen van het probleem. Dat is de reden waarom ik afzien van het kiezen van een geaccepteerd antwoord.
UTF8-CPP: UTF-8 in C++ in een Draagbare Manier
U kunt het uittreksel
utf8_codecvt_facet
van Boost-serialization-bibliotheek.Hun voorbeeld van gebruik:
Kijk voor
utf8_codecvt_facet.hpp
enutf8_codecvt_facet.cpp
bestanden in de boost-bronnen.De probleem definitie is uitdrukkelijk bepaald dat de 8-bit karakter codering is UTF-8. Dat maakt dit een triviaal probleem; het enige dat nodig is een beetje-twiddling te zetten van de ene UTF de bonnefooi naar de andere.
Kijk maar naar de coderingen op deze Wikipedia pagina ‘ s zijn voor UTF-8, UTF-16, en UTF-32.
Het principe is eenvoudig – ga door de ingang en het opstellen van een 32-bits Unicode-code-point volgens een UTF spec, dan stralen de code volgens de andere spec. De individuele code punten geen vertaling nodig, wat nodig zou zijn met een ander karakter codering; dat is wat maakt dit een simpel probleem.
Hier is een snelle uitvoering van
wchar_t
naar UTF-8 conversie en vice versa. Het gaat ervan uit dat de input is al goed gecodeerd – het oude gezegde: “Garbage in, Garbage out’ is hier van toepassing. Ik geloof dat het verifiëren van de codering gebeurt best in een aparte stap maken.De bovenstaande code werkt voor zowel UTF-16 en UTF-32-ingang, gewoon omdat het bereik
d800
doordfff
zijn ongeldige code punten; ze geven aan dat je het decoderen van UTF-16. Als u weet datwchar_t
is 32 bits dan kon je er een paar verwijderen code voor het optimaliseren van de functie.Weer als je weet dat
wchar_t
is 32 bits je kon verwijder enkele code van deze functie, maar in dit geval zou het geen verschil maken. De uitdrukkingsizeof(wchar_t) > 2
is bekend tijdens het compileren, zodat een fatsoenlijke compiler herkent de dode code en verwijder deze.wchar_t
. Ik heb bijgewerkt het antwoord.Er zijn verschillende manieren om dit te doen, maar de resultaten zijn afhankelijk van wat de karakters worden in de
string
enwstring
variabelen.Als u weet dat de
string
ASCII is, je kan gewoon gebruik maken vanwstring
’s iterator constructor:Als uw
string
heeft een aantal andere codering, maar krijg je erg slechte resultaten. Indien de codering op Unicode, je kon een kijkje nemen op de ICU project, die voorziet in een cross-platform verzameling bibliotheken voor het omzetten naar en van allerlei Unicode-coderingen.Als uw
string
bevat tekens in een code pagina, dan kan $GODHEID genadig zijn op uw ziel.ConvertUTF.h
ConvertUTF.c
Krediet te bames53 voor het verstrekken van bijgewerkte versies
Kunt u gebruik maken van de
codecvt
landinstelling facet. Er is een specifieke specialisatie gedefinieerd,codecvt<wchar_t, char, mbstate_t>
die van nut kan zijn voor u, hoewel, het gedrag van dat systeem-specifieke, en garandeert niet dat de conversie naar UTF-8 op geen enkele manier.encoding
in plaats vanlocale
. Voor zover ik kan vertellen, er is geen een landinstelling die kan vertegenwoordigen elke enkel unicode-teken. Laten we zeggen dat ik wil coderen een string met alle unicode-tekens, die landinstelling u sugguest mij te configureren? Corret me als ik verkeerd ben.UTFConverter – bekijk deze bibliotheek.
Het doet een dergelijke omzetting, maar je moet ook ConvertUTF klasse – ik heb het gevonden hier
Gemaakt van mijn eigen bibliotheek voor utf-8 en utf-16/utf-32 conversie – maar besloten om een afsplitsing van een bestaand project voor dat doel.
https://github.com/tapika/cutf
(Afkomstig uit https://github.com/noct/cutf )
API werkt met gewone C als C++.
Functie prototypes ziet er als volgt uit: (Voor de volledige lijst zie https://github.com/tapika/cutf/blob/master/cutf.h )
Voorbeeld van gebruik en /of eenvoudige test applicatie voor utf-conversie testen:
En als deze bibliotheek niet voldoen aan uw wensen – voel je vrij om te openen de volgende link:
http://utf8everywhere.org/
en scroll naar beneden op het einde van een pagina en pick-up een zwaardere bibliotheek die u wilt.
Ik denk niet dat er een draagbare manier om dit te doen. C++ kent niet de codering van de multibyte-tekens.
Als Chris voorgesteld, uw beste inzet is om te spelen met codecvt.