I would like to replace utf8 characters to byte values for easier character display handling. The actual replacement table comes from the lcd datasheet therefore it is not utf8 to ascii conversion. Hence I would like to define some macros, where I put the utf8 character, and it returns some matching hex code.
Here is the bare minimum code:
#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() {}
It does not compile and I must be missing something obvious or rather basic. Any help is much appreciated.
2 Answers 2
#define IV('┌') 0xC9
That really isn't how macros work. What goes in the brackets is a named parameter that is then used in the body of the macro. You can't have multiple macros named the same like that.
The simplest thing to do is just make a set of macros named after what the character is. For example:
#define CHR_DEGREE 0xc9
#define CHR_BOX_TL 0xB2
char line1[4] = {CHR_BOX_TL, '4', CHR_DEGREE, 0};
-
I do not want to have english names of the chars as defines, the whole point of my post is be able to do semi-ascii art. Some kind of lookup table is desirable.user12933– user129332020年12月20日 17:16:28 +00:00Commented Dec 20, 2020 at 17:16
-
UTF-8 is not a simple 1:1 mapping. It uses character sequences of variable length. A simple lookup table is not possible.Majenko– Majenko2020年12月20日 17:22:25 +00:00Commented Dec 20, 2020 at 17:22
-
I came up with a solution, please see below. I hope you or someone else has a better way to do it.user12933– user129332020年12月20日 19:06:54 +00:00Commented Dec 20, 2020 at 19:06
-
@user12933 There's a flaw in your design: a
char
can't contain a UTF-8 multi-byte character,Majenko– Majenko2020年12月20日 19:08:57 +00:00Commented Dec 20, 2020 at 19:08 -
Does it count that it compiles and works as expected irl on a real lcd screen? (just tested it, no artifacts every char/symbol show up)user12933– user129332020年12月20日 19:16:52 +00:00Commented Dec 20, 2020 at 19:16
After some googling I came up with this solution. I really hope someone finds a more elegant way to express it. These embedded ternary operators are really error prone.
#define IV(i) ( \
(i)=='┌' ? 0xc9 : \
(i)=='⎩' ? 0x15 : \
(i)=='⎭' ? 0x17 : \
(i)=='⎰' ? 0x18 : \
(i)=='°' ? 0xb2 : \
(i)=='TM' ? 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('TM'), '1', IV('┌'), '5', IV('⎰'), '5', '0', '0', IV('°'), ' ', ' ', ' ', ' ', ' ', 0}; //wanted
void setup() {}
void loop() {}
-
Macros can give weird errors is you do not parenthesize them properly. Here, you have lots of useless parentheses, yet the ones that would be needed to make the macro safe are missing. With only the required parentheses it would look like:
#define IV(i) ((i)=='┌' ? 0xc9 : (i)=='⎩' ? 0x15 : (i)=='⎭' ? 0x17 : (i)=='⎰' ? 0x18 : (i)=='°' ? 0xb2 : (i)=='TM' ? 0xd0 : (i)=='Ξ' ? 0xd8 : (i))
Edgar Bonet– Edgar Bonet2020年12月20日 20:12:02 +00:00Commented Dec 20, 2020 at 20:12 -
@EdgarBonet ty, corrected.user12933– user129332020年12月20日 20:24:07 +00:00Commented Dec 20, 2020 at 20:24