Как мне написать фасет std::codecvt?

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

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

2 ответа

Решение

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

наслаждаться

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

Важные уведомления

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

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

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

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

Другие вопросы по тегам