C++ obsługuje kodowanie znaków za pomocą std::locale
i aspektu std::codecvt
. Ogólną ideą jest to, że obiekt locale
opisuje aspekty systemu, które mogą różnić się w zależności od kultury, języka (człowieka) do języka. Aspekty te są podzielone na facet
s, które są argumentami szablonu, które definiują sposób konstruowania obiektów zależnych od lokalizacji (włącznie ze strumieniami We/Wy). Po przeczytaniu z istream
lub zapisaniu do ostream
, rzeczywiste zapisywanie każdego znaku jest filtrowane poprzez fasety ustawień narodowych. Fasety obejmują nie tylko kodowanie znaków Unicode, ale także różne funkcje, takie jak zapisywanie dużych liczb (na przykład przecinkami lub kropkami), waluty, czasu, wielkich liter i mnóstwa innych szczegółów.
Jednak tylko dlatego, że istnieją urządzenia do kodowania, nie oznacza to, że biblioteka standardowa obsługuje wszystkie kodowania, ani nie czyni tego kodu prostym do zrobienia. Nawet takie podstawowe rzeczy, jak rozmiar postaci, którą powinieneś czytać (nie mówiąc już o kodowaniu) są trudne, ponieważ wchar_t
może być zbyt mały (zniekształcanie danych) lub zbyt duży (marnowanie miejsca) i najbardziej powszechne kompilatory (np. Visual C++ i Gnu C++) do różnią się tym, jak duża jest ich implementacja. Więc zazwyczaj musisz znaleźć zewnętrzne biblioteki, aby wykonać faktyczne kodowanie.
- iconv jest ogólnie uznawany za poprawny, ale trudno znaleźć przykłady tego, jak powiązać go z mechanizmem C++.
- jla3ep mentionslibICU, która jest bardzo dokładna, ale C++ API nie próbuje grać ładnie ze standardem (o ile mogę powiedzieć. Można skanować examples aby sprawdzić, czy można to zrobić lepiej)
Najprostszym przykładem, jaki mogę znaleźć, obejmującym wszystkie bazy, jest Boost UTF-8 codecvt facet, z przykładem, który w szczególności próbuje kodować UTF-8 (UCS4) do użytku przez strumienie IO. Wygląda na to, chociaż nie sugeruję po prostu skopiować go dosłownie. To zajmuje trochę więcej kopanie w the source go zrozumieć (i nie mam zastrzeżeń do):
typedef wchar_t ucs4_t;
std::locale old_locale;
std::locale utf8_locale(old_locale,new utf8_codecvt_facet<ucs4_t>);
...
std::wifstream input_file("data.utf8");
input_file.imbue(utf8_locale);
ucs4_t item = 0;
while (ifs >> item) { ... }
Aby zrozumieć więcej o lokalizacjach, oraz sposób ich używać aspekty (w tym codecvt
), przyjrzeć się następujące :
jak zaimportować strumienie z ustawieniami regionalnymi. http://stackoverflow.com/questions/207662/writing-utf16-to-file-in-binary-mode/208431#208431 –