Парсинг String с русскими символами
- Войдите на сайт для отправки комментариев
Втр, 21/01/2020 - 13:31
До сих пор не сталкивался, думал все просто, а получилось как всегда - не выходит аленький цветочек! После долгих мучений дошло, что проблема именно в типе String, начал разбираться, для чего черкнул простенький пример:
String s ="Привет"; Serial.println(s); //печатаю всю строку, печатается "Привет" Serial.println(s.length()); //печатаю длину строки, печатается 12, хотя по факту 6 символов... Видимо русский символ считается за 2. for (int i = 0; i <= s.length(); i++) { Serial.print(s[i]); } //печатаю посимвольно - печатает квадратики, символов нет...
Вопрос знающим: как мне взять и напечатать отдельно взятый символ (несколько символов) из русской строки? У меня есть в голове пару вариантов, но все громоздкие костыли. Не может быть, что бы не было простого решения для столь тривиальной проблемы.
за UTF-8 знаешь чонибуть?
за UTF-8 знаешь чонибуть?
Немного знаю, но это не меняет вопроса: есть ли простой стандартный способ выдрать нужный русский символ из String? Например из такой "Hello1234Привет!".
Нет.
хранить и обрабатывать все в однобайтовой кодировке, например в WIN1251, а уже перед выводом преобразовывать как надо.
FoxJone - Вас ваш собственный комментарий в строке 3 ни на какие мысли не наталкивает? "Русский символ" состоит из звух байт, а вы печаете только один - конечно получается ерунда...
FoxJone - Вас ваш собственный комментарий в строке 3 ни на какие мысли не наталкивает? "Русский символ" состоит из звух байт, а вы печаете только один - конечно получается ерунда...
Да знаю я, что национальные символы два байта занимают. Вопрос состоит в том, как быстро и без геммора этот символ распознать и вычленить. Была надежда, что это все делается штатными средствами языка.
Но не больно то и хотелось, мне этот стринг только для отладки нужен, пока шрифты не прорисованы. Пожалуй, начну со шрифтов - их все равно рисовать.
У меня просто идет поток байтов (традиционно не от меня, а от чужой железки), в котором идет текст. Русский, английский, цифры... У них там своя кодировка, каждый байт означает один символ. К примеру, пробел у них байт со значением 0 (Sic!). Руки бы поотрывал...
Мне этот поток надо превратить в символы на табло. Ничего сложного, просто фонт прорисовать. Но я хотел предварительно в мониторе на все это посмотреть. Но не судьба.
Мне этот поток надо превратить в символы на табло. Ничего сложного, просто фонт прорисовать. Но я хотел предварительно в мониторе на все это посмотреть. Но не судьба.
Вы хотите рисовать кастомный фонт под чужую кодировку? - а не проще перекодировать чужую кодировку в кодировку фонта? - по мне так второй метод на порядок менее трудоемкий, к тому же позволяет легко использовать кучу фонтов. а не один единственный.
Вы хотите рисовать кастомный фонт под чужую кодировку? - а не проще перекодировать чужую кодировку в кодировку фонта? - по мне так второй метод на порядок менее трудоемкий, к тому же позволяет легко использовать кучу фонтов. а не один единственный.
Фонт все равно рисовать, его еще не существует в принципе. И вариант с фонтом мне кажется более оптимизированный в плане того, что там просто вызываешь нужный символ по значению байта и никаких лишних телодвижений. А нарисовать фонт - делов то на час, я же не каждый символ буду отрисовывать, а в основном копи-паст.
А нарисовать фонт - делов то на час
ну тут кому что проще :) Написать перекодировщик - это 10, ну может 20 строк на Си... А фонтов готовых в интернете сотни...
ну тут кому что проще :) Написать перекодировщик - это 10, ну может 20 строк на Си... А фонтов готовых в интернете сотни...
Повторюсь: вопрос то в оптимизации. У меня там ДМД работает (а он тяжелый), там 485-й с буфером, там фонты (3 штуки разных одновременно). А давайте еще 20 строк на Си добавим, которые на лету будут перекодировать байтовую посылку (а ведь еще надо таблицу перекодировки...).
А чип то у меня до сих пор 328, мозгов то, как улитки... Давно пора перейти на СТМ, но платы то у меня под 328 разведены (за деньги и новые разводить - тоже деньги...) и на заводе платном мои шаблоны есть, а новые шаблоны тоже денег стоят...
Так и живем)
Чтобы выцепить нужный символ в строке в кодировке UTF-8, надо, побайтово:
1. прочитали байт, вычислили, сколько следующих байт занимает символ;
2. Прочитали эти байты в буфер, получили байты, которые кодируют очередной символ в строке.
Собственно, всё. Кодировщиков/раскодировщиков UTF-8 - как г-на за баней. Если у вас задача работать с UTF-8 для вывода русских слов на дисплей - то тут очень много специфики, например, какая либа используется для работы с TFT, какие шрифты используются, и т.п. В общем случае задача вывода решается введением таблицы перекодировки русских символов выводимой строки (которая в UTF-8), в коды символов используемого шрифта.
Всё решаемо, но зависит от специфики. У меня во всех прошивках UTF-8, русские строки выводятся на дисплей именно по описанному алгоритму.
Вот, если интересно - выдрано из проекта работы с DMD:
Пример использования:
Как видно, в функции convertFromUTF8ToDisplayFont реализован ремаппинг UTF-8 в коды символов шрифта. Кстати до кучи - есть функция utf8_strlen - которая возвращает длину текста в символах, а не в байтах ;)
Это все я в курсе. Делать не буду, лениво и не особо надо. Если читали, мне это надо было только для отладки.
Я просто пробил, вдруг есть какой то способ одной командой, а я то его и не знаю...
Как видно, в функции convertFromUTF8ToDisplayFont реализован ремаппинг UTF-8 в коды символов шрифта. Кстати до кучи - есть функция utf8_strlen - которая возвращает длину текста в символах, а не в байтах ;)
Оппа! Точно! Я ведь этот проект и знаю хорошо, а чет даже и в голову не пришло.
Спасибо, коллега, сейчас голову поковыряю себе.
PS. Коллективный разум - это сила! Особливо распределенная БД по программированию)
PS. Коллективный разум - это сила! Особливо распределенная БД по программированию)
Тут, как видно, попроще - только табличку ремаппинга подобрать ручками - и всё.