在C和NCURSES中处理Unicode字符。

问题描述 投票:1回答:1

我想在一个C程序中显示一些unicode字符。下面可以看到一个工作的MWE。

#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;
}

编译时使用 gcc -o shades shades.c -lncursesw. 它编译得很好,并且正确地显示了阴影,正如我们在下图中看到的那样。

shades

但是使用 case/switch 语句,我想把我的角色放到一个 阵列 的十六进制代码,并对其进行迭代。如下面这个可耻的尝试。

#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;
}

这里我使用的是 sprintf 将十六进制数值转换成格式为 \u0000 哪儿 0000 是正确的十六进制值。然后我用 mvaddstr 正如我在之前的代码中所做的那样,因为 mvaddstr 期待 const char * 在第三个论点中。

这是众多失败的尝试之一。我不能正确地复制unicode格式的字符串,也不能使用一个变量作为参数到 mvaddstr 当我尝试添加unicode内容时,会出现问题。

我想知道如何才能格式化具有unicode功能的内容。const char *uint 有效的十六进制值,将其插入到一个新的字符中。mvaddstr?

PS:我在Linux中没有使用C++只是普通的C。C++的解决方案不是一个解决方案

c unicode ncurses
1个回答
1
投票

你可以简单地把字符串放在你的数组中。

const char *shades[] = { "\u2588",
                         "\u2593",
                         "\u2592",
                         "\u2591",
                         " "};

for(int x = 0; x < 20; x++)
{
    mvaddstr(1, x, shades[x%4]);
}

如果你想用代码点来做,你需要把它编码为UTF8(或任何NCurse期望的)。

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);
}

1
投票

你可以简单地使用 wctomb 铸造 wchar_t 将十六进制转换为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);
}
© www.soinside.com 2019 - 2024. All rights reserved.