Как написать фасет std:: codecvt?
Как написать фасет std:: codecvt? Я бы хотел написать те, которые идут от UTF-16 до UTF-8, которые идут от UTF-16 до текущей текущей кодовой страницы систем (Windows, так CP_ACP) и к кодовой странице OEM-системы (Windows, поэтому CP_OEM).
Предпочтительна кросс-платформа, но MSVC на Windows тоже прекрасен. Существуют ли какие-либо учебные пособия или что-то в этом роде о том, как правильно использовать этот класс?
Ответы
Ответ 1
Я написал один на основе iconv. Его можно использовать в окнах или на любой ОС POSIX.
(Вам нужно будет связать с iconv, очевидно).
Наслаждайтесь
Ответ на вопрос "как" заключается в следующем: ссылка codecvt. Еще два года назад я не смог найти лучшие инструкции в Интернете.
Важные замечания
- теоретически нет необходимости в такой работе. codecvt_byname должно быть достаточно на любой стандартной поддерживающей платформе. Но на самом деле есть некоторые компиляторы, которые не поддерживают или плохо поддерживают этот класс.
Существует также различие в интерфейсах codecvt_byname для разных компиляторов.
- мой рабочий пример реализован с параметром шаблона состояния codecvt. Всегда используйте стандартный тип mbstate, так как это единственный способ использовать ваш codecvt со стандартными классами iostream.
- std:: mbstate_t не может использоваться как указатель на 64-битных платформах межплатформенным способом.
- Преобразование stateless работает для коротких строк, но может потерпеть неудачу, если вы попытаетесь преобразовать кусок данных, превышающий размер внутреннего буфера streambuf (UTF - это, по сути, кодирование с сохранением состояния).
Ответ 2
Проблема с этим std:: codecvt - это решение, ищущее проблему. Вернее, проблема, которую она пытается решить, неразрешима, поэтому любой, кто пытается использовать ее в качестве решения, будет очень разочарован.
Если вы не знаете, какой символ задает ваш вход или выход, тогда std:: codecvt никогда не сможет вам помочь. И наоборот, если вы знаете, какие наборы символов вы используете, вы можете тривиально конвертировать между ними с помощью одного вызова функции. Обтекание вызова этой функции сложным беспорядком шаблонов не изменяет эти основы.
... и поэтому никто не использует std:: codecvt. Я рекомендую вам просто делать то, что делают все остальные, и притворяться, что этого не произошло.