简体   繁体   English

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

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

I am a C beginner and trying this and that.我是一个 C 初学者并尝试这个和那个。

Generally, I want to use special charaters "blocks" to have some kind of percentage display.一般来说,我想使用特殊字符“块”来进行某种百分比显示。

one is a kind of pie chart on a 3x3 char matrix, one is just going upwards filling a char from the bottom to the top, and eventually a string of two chars shall from left to right display the grow to 100 percent.一种是 3x3 字符矩阵上的饼图,一种是从下向上填充一个字符,最后一串两个字符从左到右显示增长到 100%。

Pricipally it seems to work out, but obviously my console has some problems to display the output.基本上它似乎可以解决,但显然我的控制台在显示 output 时存在一些问题。 non correctly displayed chars seem to lead stdout not to come to \n.未正确显示的字符似乎导致标准输出不来 \n。

Some research make me believe that the locale settings of the terminal (bash on a debian derivat) have some problem to show the chars, while Code::Blocks has no problems to show the chars and some of the chars are even shown correctly.一些研究让我相信终端的语言环境设置(debian 派生类上的 bash)在显示字符方面存在一些问题,而 Code::Blocks 在显示字符方面没有问题,并且某些字符甚至可以正确显示。 sorry, also I am some confused about unicode and utf-8 here.对不起,我也对 unicode 和 utf-8 感到有些困惑。

on the screenshow below you can see some code displayed, my locale settings, and some output of the code.在下面的屏幕显示中,您可以看到显示的一些代码、我的语言环境设置以及代码的一些 output。

How can I solve the problem?我该如何解决这个问题?

BTW: I would like to stick to printf if possible to keep things easy for me.顺便说一句:如果可能的话,我想坚持使用 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;
}

a simple screenie一个简单的屏幕

As I guessed in a comment , the major problem is that your code tries to store too much data in arrays that are too small.正如我在评论中猜测的那样,主要问题是您的代码试图在太小的 arrays 中存储太多数据。

When I copy your code, it doesn't compile because the strings initializing the array are too big.当我复制您的代码时,它不会编译,因为初始化数组的字符串太大。 The characters you're using seem to be in the range U+2580..U+259F, which means that they require 3 bytes when represented in UTF-8 (U+2580 = 0xE2 0x96 0x80 = U+2580; 0xE2 0x96 0x9F = U+259F).您使用的字符似乎在 U+2580..U+259F 范围内,这意味着当以 UTF-8 表示时它们需要 3 个字节(U+2580 = 0xE2 0x96 0x80 = U+2580;0xE2 0x96 0x9F = U +259F)。

You have to increase the size of your arrays — C counts bytes, not characters when using char , signed char or unsigned char .您必须增加 arrays 的大小 — C 计算字节数,而不是使用charsigned charunsigned char时的字符数。 Using 16 is overkill;使用16是大材小用; 10 would be sufficient; 10就足够了; likewise 8 could be just 7 .同样8可能只是7 You also need to treat the percentageUpwards array as an array of strings of at least size 4. Putting those changes together yields this code, which more or less works on both a Mac running (sigh) macOS 10.14.6 Mojave and a Linux box running RHEL Server release 7.4 (Maipo) — the latter running over ssh into a Terminal on the Mac.您还需要将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;
}

I can't sensibly show the output;我无法明智地展示 output; it is dynamic and takes about 26 seconds to execute because of the msleep() calls.由于msleep()调用,它是动态的,执行大约需要 26 秒。

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

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