[英]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 计算字节数,而不是使用char
、 signed char
或unsigned 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.