Reputation: 1203
I'm trying to display some unicode characters in a C program. A working MWE can be seen below:
#include <ncurses.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <locale.h>
int main(int argc, char *argv[])
{
setlocale(LC_ALL, "");
initscr(); // Initialize stdscr
for(int x = 0; x < 20; x++)
{
switch (x%5)
{
case 0:
mvaddstr(1, x, "\u2588");
break;
case 1:
mvaddstr(1, x, "\u2593");
break;
case 2:
mvaddstr(1, x, "\u2592");
break;
case 3:
mvaddstr(1, x, "\u2591");
break;
case 4:
mvaddstr(1, x, " ");
break;
}
}
mvprintw(3, 0, "Press ANY KEY to finish");
refresh();
int ch = getch();
endwin();
return 0;
}
To compile use gcc -o shades shades.c -lncursesw
. It compiles fine and shows the shades correctly, as we can see in image below.
But instead using a case/switch
statement I would like put my characters into an array of hexadecimal codes and iterate over it. As the shameful attempt below.
#include <ncurses.h>
#include <stdlib.h>
#include <stdio.h>
#include <locale.h>
int main(int argc, char *argv[])
{
setlocale(LC_ALL, "");
initscr(); // Initialize stdscr
uint shades[5] = { 0x2588,
0x2593,
0x2592,
0x2591,
' '};
char utfchar[7];
for(int x = 0; x < 20; x++)
{
sprintf(utfchar, "\\u%04x", shades[x%5]);
mvaddstr(1, x, utfchar);
}
mvprintw(3, 0, "Press ANY KEY to finish");
refresh();
int ch = getch();
endwin();
return 0;
}
Here I'm using sprintf
to convert the hexadecimal value into a string formatted as \u0000
where 0000
are the correct hexadecimal value. Then I use mvaddstr
as I did in previous code, since mvaddstr
expects a const char *
in third argument.
This is one of the many failed attemps. I'm not being able to copy the strings correctly in unicode format, neither being able to use a variable as argument to mvaddstr
when I try to add unicode content.
I would like to know how can I format the unicode capable const char *
from a uint
valid unicode hex value to insert it into the mvaddstr
?
PS: I'm not using C++ just plain C in Linux. C++ solutions are not a solution
Upvotes: 0
Views: 1899
Reputation: 41017
You can simply use wctomb
casting with wchar_t
to convert from hex to unicode:
uint shades[5] = { 0x2588,
0x2593,
0x2592,
0x2591,
' '};
char utfchar[MB_CUR_MAX];
for(int x = 0; x < 20; x++)
{
memset(utfchar, 0, sizeof utfchar);
wctomb(utfchar, (wchar_t)shades[x % 5]);
mvaddstr(1, x, utfchar);
}
Upvotes: 1
Reputation: 1030
You could simply put the strings in your array:
const char *shades[] = { "\u2588",
"\u2593",
"\u2592",
"\u2591",
" "};
for(int x = 0; x < 20; x++)
{
mvaddstr(1, x, shades[x%4]);
}
If you want to do it with codepoints, you need to encode it as UTF8 (or anything NCurse expects):
void sprintutf8(char *buffer, uint32_t code)
{
if (code < 0x80)
sprintf(buffer, "%c", code);
else if (code < 0x800)
sprintf(buffer, "%c%c",
0xC0 | (code >> 6),
0x80 | (code & 0x3F));
else
sprintf(buffer, "%c%c%c",
0xE0 | (code >> 12),
0x80 | (code >> 6 & 0x3F),
0x80 | (code & 0x3F));
}
[...]
for(int x = 0; x < 20; x++)
{
sprintutf8(utfchar, shades[x%4]);
mvaddstr(1, x, utfchar);
}
Upvotes: 1