С ++ поддерживает кодировку символов с помощью std::locale
и фаски std::codecvt
. Общая идея заключается в том, что объект locale
описывает аспекты системы, которые могут варьироваться от культуры к культуре, (человеческого) языка и языка. Эти аспекты разбиты на facet
s, которые являются аргументами шаблона, которые определяют, как строятся объекты, зависящие от локализации (включая потоки ввода-вывода). Когда вы читаете istream
или записываете в ostream
, фактическая запись каждого символа фильтруется через грани местности. Границы охватывают не только кодировку типов Unicode, но и такие разнообразные функции, как то, как большие числа записываются (например, с запятыми или периодами), валютой, временем, капитализацией и множеством других деталей.
Однако только потому, что средства существуют для кодирования, не означает, что стандартная библиотека фактически обрабатывает все кодировки и не делает такой код простым в правильном направлении. Даже такие основные вещи, как размер символа, который вы должны читать (не говоря уже о части кодирования), сложны, так как wchar_t
может быть слишком маленьким (искажать ваши данные) или слишком большим (пустым пространством) и наиболее распространенными компиляторами (например Visual C++ и Gnu C++) do отличаются от того, насколько велика их реализация. Поэтому вам обычно нужно найти внешние библиотеки для фактической кодировки.
- iconv, как правило, признают правильными, но примеры того, как связать его с механизмом C++, трудно найти.
- jla3ep mentionslibICU, который очень тщательно, но C++ API не пытается красиво играть со стандартом (Насколько я могу сказать:. Вы можете сканировать examples, чтобы увидеть, если вы можете сделать лучше)
Самый простой пример, который я могу найти, который охватывает все базы, - от Boost's UTF-8 codecvt facet, с примером, который специально пытается кодировать UTF-8 (UCS4) для использования потоками ввода-вывода. Это похоже на это, хотя я не предлагаю просто копировать его дословно. Это займет немного больше копаться в the source, чтобы понять это (и я не претендую на):
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) { ... }
Чтобы понять больше о локалях, и как они используют грани (в том числе codecvt
), обратите внимание на следующем :
Как наполнить потоки с помощью локали. http://stackoverflow.com/questions/207662/writing-utf16-to-file-in-binary-mode/208431#208431 –