繁体   English   中英

C 编程,Unicode/UTF-8 特殊字符未显示在 linux 控制台上

[英]C programming, unicode/UTF-8 special characters not showing up on linux console

我是一个 C 初学者并尝试这个和那个。

一般来说,我想使用特殊字符“块”来进行某种百分比显示。

一种是 3x3 字符矩阵上的饼图,一种是从下向上填充一个字符,最后一串两个字符从左到右显示增长到 100%。

基本上它似乎可以解决,但显然我的控制台在显示 output 时存在一些问题。 未正确显示的字符似乎导致标准输出不来 \n。

一些研究让我相信终端的语言环境设置(debian 派生类上的 bash)在显示字符方面存在一些问题,而 Code::Blocks 在显示字符方面没有问题,并且某些字符甚至可以正确显示。 对不起,我也对 unicode 和 utf-8 感到有些困惑。

在下面的屏幕显示中,您可以看到显示的一些代码、我的语言环境设置以及代码的一些 output。

我该如何解决这个问题?

顺便说一句:如果可能的话,我想坚持使用 printf 以使事情变得容易。

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

// some little helpers
# define hideCursor() printf("\e[?25l")
# define showCursor() printf("\e[?25h")
# define clear() printf("\033[H\033[J")

// # define WIDE_ORIENTED 1

int msleep(long tms);

int main()
{
setlocale(LC_ALL, "");
// fwide( stdout, WIDE_ORIENTED );

char percentage[21][4][4] = {{"   ","   ","   ","  0"},
                             {" ▐ ","   ","   ","  5"},
                             {" ▐▌","   ","   "," 10"},
                             {" ▐▛","   ","   "," 15"},
                             {" ▐█","   ","   "," 20"},
                             {" ▐█","  ▀","   "," 25"},
                             {" ▐█","  █","   "," 30"},
                             {" ▐█","  █","  ▀"," 35"},
                             {" ▐█","  █","  ▜"," 40"},
                             {" ▐█","  █","  █"," 45"},
                             {" ▐█","  █"," ▐█"," 50"},
                             {" ▐█","  █"," ██"," 55"},
                             {" ▐█","  █","▐██"," 60"},
                             {" ▐█","  █","▟██"," 65"},
                             {" ▐█","  █","███"," 70"},
                             {" ▐█","▄ █","███"," 75"},
                             {" ▐█","█ █","███"," 80"},
                             {"▄▐█","█ █","███"," 85"},
                             {"▙▐█","█ █","███"," 90"},
                             {"█▐█","█ █","███"," 95"},
                             {"███","█ █","███","100"}};

char percentageUpwards[10] = {" ▁▂▃▄▅▆▇██"};

char percentageSidewards[20][2] = {"  ","▏ ","▎ ","▍ ","▌ ","▌ ","▋ ","▊ ","█ ","▉ ","▉▏","▉▎","▉▍","▉▌","▉▌","▉▋","▉▊","▉█","▉▉","▉▉"};


// does already nor work :-/
    clear();
    int counter = 0;
    for (int i = 0 ; i <= 100 ; i++) {
    //printf("%d %d\n", (i), (i % 5));
        if ((i % 5) == 0) {
            clear();
            printf("Squared Percentage:\n");
            printf("%s\n",percentage[counter][0]);
            printf("%s\n",percentage[counter][1]);
            printf("%s\n",percentage[counter][2]);
            printf("%s\n",percentage[counter][3]);
            msleep(500); // nappy for easier following
            counter++;
        }
    }

// only a percentage display going upwards
    counter = 0;
    for (int i = 0 ; i <= 100 ; i++) {
        if ((i % 11) == 0) {
            clear();
            printf("Upwards:\n");
            printf("%c\n", percentageUpwards[counter]);
            fflush(stdout);
            printf("%d\n", i);
            msleep(500); // nappy for easier following
            counter++;
        }
    }

// only a percentage display going upwards
    counter = 0;
    for (int i = 0 ; i <= 100 ; i++) {
        if ((i % 5) == 0) {
            clear();
            printf("Sidewards:\n");
            printf("%s\n", percentageSidewards[counter]);
            fflush(stdout);
            printf("%d\n", i);
            msleep(500); // nappy for easier following
            counter++;
        }
    }

// Test only
printf("%s\n", percentage[15][0]);
printf("%s\n", percentage[15][1]);
printf("%s\n", percentage[15][2]);
printf("%s\n", percentage[15][3]);
printf("\n");
printf("%c\n", percentageUpwards[5]);
printf("\n");
printf("%s\n", percentageSidewards[10]);

    return 0;
}

// have a nap in 1/1000th of a second steps
int msleep(long tms)
{
    struct timespec ts;
    int ret;
    if (tms < 0) {
        return -1;
    }
    ts.tv_sec = tms / 1000;
    ts.tv_nsec = (tms % 1000) * 1000000;
    do {
        ret = nanosleep(&ts, &ts);
    }
    while (ret);
    return ret;
}

一个简单的屏幕

正如我在评论中猜测的那样,主要问题是您的代码试图在太小的 arrays 中存储太多数据。

当我复制您的代码时,它不会编译,因为初始化数组的字符串太大。 您使用的字符似乎在 U+2580..U+259F 范围内,这意味着当以 UTF-8 表示时它们需要 3 个字节(U+2580 = 0xE2 0x96 0x80 = U+2580;0xE2 0x96 0x9F = U +259F)。

您必须增加 arrays 的大小 — C 计算字节数,而不是使用charsigned charunsigned char时的字符数。 使用16是大材小用; 10就足够了; 同样8可能只是7 您还需要将percentageUpwards数组视为至少大小为 4 的字符串数组。将这些更改放在一起会产生此代码,该代码或多或少适用于运行 macOS 10.14.6 Mojave 的 Mac 和运行的 Linux 盒子RHEL 服务器版本 7.4 (Maipo) — 后者通过ssh运行到 Mac 上的终端中。

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <time.h>

// some little helpers
# define hideCursor() printf("\e[?25l")
# define showCursor() printf("\e[?25h")
# define clear() printf("\033[H\033[J")

// # define WIDE_ORIENTED 1

int msleep(long tms);

int main(void)
{
    setlocale(LC_ALL, "");
// fwide( stdout, WIDE_ORIENTED );

    char percentage[21][4][16] =
    {
        { "   ", "   ", "   ", "  0" },
        { " ▐ ", "   ", "   ", "  5" },
        { " ▐▌", "   ", "   ", " 10" },
        { " ▐▛", "   ", "   ", " 15" },
        { " ▐█", "   ", "   ", " 20" },
        { " ▐█", "  ▀", "   ", " 25" },
        { " ▐█", "  █", "   ", " 30" },
        { " ▐█", "  █", "  ▀", " 35" },
        { " ▐█", "  █", "  ▜", " 40" },
        { " ▐█", "  █", "  █", " 45" },
        { " ▐█", "  █", " ▐█", " 50" },
        { " ▐█", "  █", " ██", " 55" },
        { " ▐█", "  █", "▐██", " 60" },
        { " ▐█", "  █", "▟██", " 65" },
        { " ▐█", "  █", "███", " 70" },
        { " ▐█", "▄ █", "███", " 75" },
        { " ▐█", "█ █", "███", " 80" },
        { "▄▐█", "█ █", "███", " 85" },
        { "▙▐█", "█ █", "███", " 90" },
        { "█▐█", "█ █", "███", " 95" },
        { "███", "█ █", "███", "100" },
    };

    char percentageUpwards[][4] =
    {
        " ", "▁", "▂", "▃", "▄", "▅", "▆", "▇", "█", "█", 
    };

    char percentageSidewards[20][8] =
    {
        "  ", "▏ ", "▎ ", "▍ ", "▌ ", "▌ ", "▋ ", "▊ ", "█ ", "▉ ",
        "▉▏", "▉▎", "▉▍", "▉▌", "▉▌", "▉▋", "▉▊", "▉█", "▉▉", "▉▉",
    };

    // does already not work :-/
    clear();
    int counter = 0;
    for (int i = 0; i <= 100; i++)
    {
        // printf("%d %d\n", (i), (i % 5));
        if ((i % 5) == 0)
        {
            clear();
            printf("Squared Percentage:\n");
            printf("%s\n", percentage[counter][0]);
            printf("%s\n", percentage[counter][1]);
            printf("%s\n", percentage[counter][2]);
            printf("%s\n", percentage[counter][3]);
            msleep(500); // nappy for easier following
            counter++;
        }
    }

    // only a percentage display going upwards
    counter = 0;
    for (int i = 0; i <= 100; i++)
    {
        if ((i % 11) == 0)
        {
            clear();
            printf("Upwards:\n");
            printf("%s\n", percentageUpwards[counter]);
            fflush(stdout);
            printf("%d\n", i);
            msleep(500); // nappy for easier following
            counter++;
        }
    }

    // only a percentage display going upwards
    counter = 0;
    for (int i = 0; i <= 100; i++)
    {
        if ((i % 5) == 0)
        {
            clear();
            printf("Sidewards:\n");
            printf("%s\n", percentageSidewards[counter]);
            fflush(stdout);
            printf("%d\n", i);
            msleep(500); // nappy for easier following
            counter++;
        }
    }

    // Test only
    printf("%s\n", percentage[15][0]);
    printf("%s\n", percentage[15][1]);
    printf("%s\n", percentage[15][2]);
    printf("%s\n", percentage[15][3]);
    printf("\n");
    printf("%s\n", percentageUpwards[5]);
    printf("\n");
    printf("%s\n", percentageSidewards[10]);

    return 0;
}

// have a nap in 1/1000th of a second steps
int msleep(long tms)
{
    struct timespec ts;
    int ret;
    if (tms < 0)
    {
        return -1;
    }
    ts.tv_sec = tms / 1000;
    ts.tv_nsec = (tms % 1000) * 1000000;
    do
    {
        ret = nanosleep(&ts, &ts);
    }while (ret);
    return ret;
}

我无法明智地展示 output; 由于msleep()调用,它是动态的,执行大约需要 26 秒。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM