Как мне написать фасет std :: codecvt? - PullRequest
12 голосов
/ 04 июня 2010

Как мне написать фасет std :: codecvt? Я хотел бы написать те, которые идут от UTF-16 до UTF-8, которые идут от UTF-16 до текущей кодовой страницы системы (windows, поэтому CP_ACP), и к кодовой странице OEM системы (windows, так CP_OEM).

Кроссплатформенность предпочтительнее, но MSVC в Windows тоже подойдет. Существуют ли какие-либо учебные пособия или что-то в этом роде о том, как правильно использовать этот класс?

Ответы [ 2 ]

9 голосов
/ 07 июня 2010

Я написал один на основе iconv. Его можно использовать в Windows или в любой операционной системе POSIX. (Вам нужно будет связаться с iconv, очевидно).

Наслаждайтесь

Ответ на вопрос «как» должен следовать за ссылкой на codecvt . Два года назад я не смог найти более качественных инструкций в Интернете.

Важные замечания

  • теоретически в такой работе нет необходимости. codecvt_byname должно быть достаточно на любой стандартной платформе поддержки. Но на самом деле есть некоторые компиляторы, которые не поддерживают или плохо поддерживают этот класс. Существует также разница в интерфейсах codecvt_byname на разных компиляторах.
  • Мой рабочий пример реализован с параметром шаблона состояния codecvt. Всегда используйте стандартный тип mbstate, так как это единственный способ использовать ваш codecvt со стандартными классами iostream.
  • Тип std :: mbstate_t нельзя использовать в качестве указателя на 64-битных платформах кроссплатформенным способом.
  • Преобразования без сохранения состояния работают для коротких строк, но могут потерпеть неудачу, если вы попытаетесь преобразовать блок данных больше, чем размер внутреннего буфера streambuf (UTF - это кодировка с сохранением состояния)
4 голосов
/ 07 июня 2010

Проблема с этим std :: codecvt в том, что это решение ищет проблему. Или, скорее, проблема, которую он пытается решить, неразрешима, поэтому любой, кто попытается использовать его как решение, будет очень разочарован.

Если вы не знаете, какой набор символов используется для ввода или вывода, std :: codecvt никогда не сможет вам помочь. И наоборот, если вы do знаете, какие наборы символов вы используете, то вы можете тривиально преобразовать их в один вызов функции. Оборачивание этого вызова функции в сложную путаницу шаблонов не меняет этих основ.

... и поэтому никто не использует std :: codecvt. Я рекомендую вам просто делать то, что делают все остальные, и делать вид, что этого никогда не было.

...