utf8 в шестнадцатеричный макрос

c++

Я хотел бы заменить символы utf8 на байтовые значения для облегчения обработки отображения символов. Фактическая таблица замены взята из таблицы данных lcd, поэтому она не является преобразованием utf8 в ascii. Поэтому я хотел бы определить некоторые макросы, куда я помещаю символ utf8, и он возвращает соответствующий шестнадцатеричный код.

Вот минимальный код:

#define IV('┌') 0xC9
#define IV('°') 0xB2

char line0[4] = {0xC9, '4', 0xB2, 0}; // works
char line1[4] = {IV('┌'), '4', IV('°'), 0}; // do not work

void setup() {}
void loop() {}

Он не компилируется, и я, должно быть, упускаю что-то очевидное или, скорее, базовое. Любая помощь очень ценится.

, 👍0


2 ответа


1
#define IV('┌') 0xC9

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

Самое простое, что можно сделать, - это просто создать набор макросов, названных в честь того, что представляет собой символ. Например:

#define CHR_DEGREE 0xc9
#define CHR_BOX_TL 0xB2

char line1[4] = {CHR_BOX_TL, '4', CHR_DEGREE, 0};
,

Я не хочу иметь английские названия символов, как определено, весь смысл моего поста в том, чтобы иметь возможность создавать полу-ascii-изображения. Желательно иметь какую-то справочную таблицу., @user12933

UTF-8 - это не простое отображение 1: 1. Он использует последовательности символов переменной длины. Простая таблица поиска невозможна., @Majenko

Я придумал решение, пожалуйста, смотрите ниже. Я надеюсь, что у вас или у кого-то другого есть лучший способ сделать это., @user12933

@user12933 В вашем дизайне есть недостаток: символ char не может содержать многобайтовый символ UTF-8,, @Majenko

Считается ли, что он компилируется и работает должным образом irl на реальном ЖК-экране? (только что протестировал, никаких артефактов при каждом символе / символе не появляется), @user12933

@user12933 Если первый байт каждого из этих символов уникален, тогда все в порядке. Он отбросит все последующие байты в символе. Вам было бы лучше использовать вместо этого wchar_t и UTF-16 (`L'┌"), @Majenko

Давайте [продолжим это обсуждение в чате] (https://chat.stackexchange.com/rooms/117485/discussion-between-user12933-and-majenko )., @user12933


0

После некоторого гугления я пришел к такому решению. Я очень надеюсь, что кто-то найдет более элегантный способ выразить это. Эти встроенные тернарные операторы действительно подвержены ошибкам.

#define IV(i) ( \
(i)=='┌' ? 0xc9 : \
(i)=='⎩' ? 0x15 : \
(i)=='⎭' ? 0x17 : \
(i)=='⎰' ? 0x18 : \
(i)=='°' ? 0xb2 : \
(i)=='™' ? 0xd0 : \
(i)=='Ξ' ? 0xd8 : \
(i) )





char line2[21] = {0x15, '_', 0xd8, '_', 0x17, 0xd0, '1', 0xc9, '5', 0x18, '5', '0', '0', 0xb2, ' ', ' ', ' ', ' ', ' ', 0}; //original
char line4[21] = {IV('⎩'), '_', IV('Ξ'), '_', IV('⎭'), IV('™'), '1', IV('┌'), '5', IV('⎰'), '5', '0', '0', IV('°'), ' ', ' ', ' ', ' ', ' ', 0}; //wanted

void setup() {}
void loop() {}
,

Макросы могут выдавать странные ошибки, если вы неправильно заключаете их в скобки. Здесь у вас есть много бесполезных круглых скобок, но те, которые были бы необходимы для обеспечения безопасности макроса, отсутствуют. Только с обязательными круглыми скобками это будет выглядеть так: #define IV (i) ((i) =='┌' ? 0xc9 : (i)=='⎩' ? 0x15 : (i) =='⎭' ? 0x17 : (i) =='⎰' ? 0x18 : (i)== '°' ? 0xb2 : (i)=='™' ? 0xd0 : (i)=='Ξ' ? 0xd8 : (i)), @Edgar Bonet

@EdgarBonet тай, исправлено., @user12933