Arlleex 207 October 22 Posted October 22 · Report post Потребовалось мне из UTF-16 конвертнуть строку в CP-866 (https://www.ascii-codes.com/cp866.html). С первой половиной ascii-кодов, вроде, проблем не должно возникнуть, т.к. их числовые значения будут сопоставимы с кодами в UTF-16 (за ислкючением занимаемой памяти в расчете на 1 символ). Но вот просмотрел список символов в Unicode-таблице, сопоставимых с соответствующей частью в CP-866 и... кто в лес, кто по дрова. Какие-то ряды букв идут подряд, какие-то идут в разрыв уже. Т.е. банальным арифметическим преобразованием (смещением некого числа) не обойтись. Да и табличный метод не особо применить. Не уж то плодить кучу if(), или я чего-то не замечаю и все не так страшно? Quote Share this post Link to post Share on other sites More sharing options...
Plain 232 October 23 Posted October 23 · Report post Оба алфавита вполне себе отсекаются простыми преобразованиями, отдельно Ё, ё, №, °, ·, далее ничего интересного, но если надо, есть стандартный способ — поиск в таблице. Quote Share this post Link to post Share on other sites More sharing options...
andrew_b 17 October 23 Posted October 23 · Report post https://www.gnu.org/software/libiconv/ 1 Quote Share this post Link to post Share on other sites More sharing options...
Arlleex 207 October 23 Posted October 23 · Report post 34 минуты назад, andrew_b сказал: https://www.gnu.org/software/libiconv/ Видимо мне стоило написать, что меня интересует исходный код Мне в микроконтроллер надо это прикрутить. Ладно, утром почитал получше об этих форматах, мне проще вручную Солнце закатить. Quote Share this post Link to post Share on other sites More sharing options...
MegaVolt 29 October 23 Posted October 23 · Report post Думаю задача не так проста как кажется. Исходники нужно искать в OpenSource библиотеках. Явно это решённый вопрос. Хотя можно и тиблицу на 64 к запилить 🙂 Quote Share this post Link to post Share on other sites More sharing options...
makc 236 October 23 Posted October 23 · Report post 14 минут назад, MegaVolt сказал: Думаю задача не так проста как кажется. Исходники нужно искать в OpenSource библиотеках. Явно это решённый вопрос. Хотя можно и тиблицу на 64 к запилить 🙂 Для общего случая не получится сделать таблицу на 64к, т.к. по описанию: Цитата UTF-16 (англ. Unicode Transformation Format) в информатике — один из способов кодирования символов из Юникода в виде последовательности 16-битных слов. Данная кодировка позволяет записывать символы Юникода в диапазонах U+0000..U+D7FF и U+E000..U+10FFFF (общим количеством 1 112 064). При этом каждый символ записывается одним или двумя словами (последнее называется суррогатная пара). Кодировка UTF-16 описана в приложении Q к международному стандарту ISO/IEC 10646, а также ей посвящён IETF RFC 2781 «UTF-16, an encoding of ISO 10646». Обратите внимание на выделенное. Quote Share this post Link to post Share on other sites More sharing options...
Сергей Борщ 155 October 23 Posted October 23 · Report post 3 часа назад, Arlleex сказал: Мне в микроконтроллер надо это прикрутить. А что именно должен делать микроконтроллер? Мне на днях нужно было выводить на графический экран русские/английские сообщения из исходника, набранного в UTF-8. Преобразование UTF8->char16_t заняло 10 строк исходника и знакогенератор на 4 диапазона (как написал Plain) : U0020-U007F (ASCII), U0410-U044F (А-я), U0401 (Ё), U0451 (ё). Да, я не обрабатываю ошибки и всякие тонкости, потому что строковые литералы в моем исходнике не содержат запрещенных комбинаций и символов со всякими умляутами по определению. Может в вашей задаче тоже можно обойтись чем-то подобным, может вам не нужны прям все-все символы CP866? 1 Quote Share this post Link to post Share on other sites More sharing options...
Arlleex 207 October 23 Posted October 23 · Report post Все символы, может, и не нужны... Но парсить придется честно (с обработкой ошибок), так как символы летят по каналу связи без проверки фреймов на валидность... МК должен принять строку в унифицированном формате, перекодировать в CP-866 и отправить получившееся в ModBus RTU (строка вывода, табло). На той же шине ModBus висит еще и другая строка, но она уже понимает UTF16. Quote Share this post Link to post Share on other sites More sharing options...
jcxz 251 October 23 Posted October 23 · Report post 18 минут назад, Arlleex сказал: Все символы, может, и не нужны... А какие именно нужны символы? От этого зависит сложность. Если только кириллица, то в чём сложность? Там со всеми проверками код немного больше пары десятков строчек. Вот участок код парсера потока входных символов для кода МК, работающего с эмулятором терминала (типа Putty) в режиме UTF-8 из моего проекта на МК (участок как раз парсит UTF-8): static s32 arg; static u32 timeEsc; static u8 state = S_INIT; static u8 cnt; uint c, j; ... if (PARSE_UTF8_DEF && (c & B7)) { //преобразование UTF-8 в Win1251 u32 cc = (u32)c << 25; if (j = CntLeadingZeros(~cc)) { if (j > 5 || state != S_NONE) return HEsc_ERROR; cnt = j; j += 26; arg = c << j >> j; state = S_UTF8; } else { if (state != S_UTF8) return HEsc_ERROR; arg = arg << 6 | cc >> 25; if (--cnt) continue; c = (cc = arg - 0x410) + 0xC0; if (cc > (uint)'я' - (uint)'А') { c = 'Ё'; if (cc += 0x410u - 0x401u) { c = 'ё'; if (cc += 0x401u - 0x451u) return HEsc_SKIP; } } state = S_INIT; return (HEsc)c; } } else if ((c & 0x7F) == 0x1B) { ... Все проверки на допустимость каждого байта вроде как имеются. При ошибках - возврат HEsc_ERROR, для ненужных (неподдерживаемых кодов) - HEsc_SKIP. Вы больше все сообщения темы придумывали, чем кода тут. Только у меня преобразование в WIN1251, а не CP866. Quote Share this post Link to post Share on other sites More sharing options...
andrew_b 17 October 23 Posted October 23 · Report post 1 minute ago, jcxz said: в режиме UTF-8 из моего проекта на МК UTF-8 != UTF-16 Quote Share this post Link to post Share on other sites More sharing options...
kochevkv 1 October 23 Posted October 23 · Report post 6 minutes ago, andrew_b said: UTF-8 != UTF-16 Так это только способ упаковки уникода, я так понимаю. Правила распаковки символа только поменять. Quote Share this post Link to post Share on other sites More sharing options...
jcxz 251 October 23 Posted October 23 · Report post 29 минут назад, andrew_b сказал: UTF-8 != UTF-16 И что? UTF-16 парсить должно быть ещё проще, чем UTF-8. 21 минуту назад, kochevkv сказал: 27 минут назад, andrew_b сказал: Так это только способ упаковки уникода, я так понимаю. Именно так. Quote Share this post Link to post Share on other sites More sharing options...
kochevkv 1 October 23 Posted October 23 (edited) · Report post 42 minutes ago, jcxz said: И что? UTF-16 парсить должно быть ещё проще, чем UTF-8. Да, я про замечание что они отличаются. Суть одна и код можно легко подогнать под UTF-16 если надо. Я бы просто таблицу u16 unicodeCp866[256] сделал если память позволяет. Самое простое и быстрое. И таблицу switch case обратно Edited October 23 by kochevkv Quote Share this post Link to post Share on other sites More sharing options...
Arlleex 207 October 23 Posted October 23 · Report post 2 минуты назад, kochevkv сказал: Да, я про замечание что они отличаются. Суть одна и код можно легко подогнать под UTF-16 если надо. Я бы просто таблицу u16 unicodeCp866[256] сделал если память позволяет. Самое простое и быстрое. Вы в суть кодирования UTF-16 вникали? Не получится там так в лоб завести одну табличку на 256 значений. 1 час назад, jcxz сказал: А какие именно нужны символы? От этого зависит сложность. Если только кириллица, то в чём сложность? Там со всеми проверками код немного больше пары десятков строчек. Кириллица + стандартный ASCII (коды 0...127), с возможностью отбраковки некорректно закодированных символов (по крайней мере, отсутствующих в CP-866). Цитата Вот участок код парсера потока входных символов для кода МК, работающего с эмулятором терминала (типа Putty) в режиме UTF-8 из моего проекта на МК (участок как раз парсит UTF-8): Мне сначала прилетает поток байтов, которые (якобы) в UTF-16. Канал потенциально не надежный, т.е. мне надо каждый символ парсить на валидность в том числе, т.е. таблицу быстрого поиска организовать не достаточно. В целом, я уже разобрался с UTF-16. Quote Share this post Link to post Share on other sites More sharing options...
kochevkv 1 October 23 Posted October 23 · Report post 8 minutes ago, Arlleex said: Вы в суть кодирования UTF-16 вникали? Не получится там так в лоб завести одну табличку на 256 значений. Из уникода в cp866 switch case. Насколько я помню, кириллица в уникоде в u16 умещается. Если там есть u32 значения то будет таблица u32 unicodeCp866[256] и аналогично 256 case'ов Quote Share this post Link to post Share on other sites More sharing options...