LINUX.ORG.RU

CPnnnn to utf-8

 , , ,


0

1

Здравствуйте. Пишу на С99 одну тулзу.

Есть ли гуманные способы перевести один символ из однобайтных кодировок в utf-8?

iconv не предлагать.

iconv не предлагать.

ICU4C?

drsm ★★
()

Голый C99 эгоистичен и требователен: http://en.cppreference.com/w/c/string/multibyte/btowc

Перед запуском приложения необходимо разложить перед ним файлы для поддержки локали ru_RU.CP1251 или С.CP1251. Это системо-зависимо; на многих дистрибутивах это делается через locale-gen.

Потом нужно показать готовность пуститься во все тяжкие вызвав смену LC_CTYPE глобальной локали всего процесса:

setlocale(LC_CTYPE, "локаль.CP1251");

Это открывает древние знания и возможность получить Unicode code point для символа при помощи btowc.

Дальше надо решительно порвать с прошлым, выставив глобальную локаль в UTF8.

setlocale(LC_CTYPE, "локаль.UTF8");

И получить заветный utf8 применив к полученному Unicode code point wcrtomb.

Почему не iconv, какие ограничения на потенциальные альтернативы?

GPFault ★★
()
Ответ на: комментарий от GPFault

Я читаю rtf.

Текст там, как правило, в очень разряженном виде. Между командами однобайтных символов могут быть управляющие команды, команды символов юникода и прочая.

Если буду использовать iconv, то утону в обилии различных буферов. Хочется сделать красиво. При нахождении команды однобайтного символа переводить его одного в utf-8 и класть в единственный выходной буфер.

Можно еще генерировать таблицу трансляции в utf8 с помощью iconv и дальше работать только с таблицей.

Cactus64k
() автор топика
Ответ на: комментарий от Cactus64k

Я так понимаю что функция генерации utf8 на основе юникод-команды типа \u12345 уже есть - то есть есть функция вывода utf8 по значению Unicode code point (что-то типа size_t wcrtomb(char *s, wchar_t wc, mbstate_t *ps);

Тогда наверное самый простой вариант такой: Взять строку, содержащую байты то 32 до 255, и попросить iconv перекодировать её в utf32 (c endian машины).

Полученные данные интерпретировать как массив int32_t single_byte_code_points[256-' '].

И при получении команды на сивол x из однобайтовой кодировки делать buffer += wcrtomb(buffer, single_byte_code_points[x-' '], ps)

То есть конвертировать при помощи таблицы, но не в utf8, где результат может быть разной длинны и простой массив не подойдёт, а в utf32, где будет достаточно одного вызова iconv, и результат будет простым массивом

GPFault ★★
()
Ответ на: комментарий от GPFault

Можно еще генерировать таблицу трансляции в utf8 с помощью iconv и дальше работать только с таблицей.

Я имел в виду что можно сделать таблицу трансляции для кодировки, указанной в \adeflang. Она будет немного сложнее, чем utf32, но более быстрой. Меньше вызовов функций перевода, где наверняка тоже используется таблица трансляции. Чтобы не заморачиваться с размером символа utf8, можно взять массив указателей на char[6];

Cactus64k
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.