【问题标题】:Printing a unicode box in C在 C 中打印一个 unicode 框
【发布时间】:2016-01-22 01:14:09
【问题描述】:

我正在尝试在 C 中打印这个中等阴影 unicode 框:▒

(我在 K&R 中做练习,然后在制作直方图的问题上偏离了方向……)。我知道我的 unix 术语 (Mac OSX) 可以显示该框,因为我使用该框保存了一个文本文件,并使用了 cat textfilewithblock 并打印了该块。

到目前为止,我最初尝试过:

#include <stdio.h>
#include <wchar.h>

int main(){
  wprintf(L"▒\n");
  return 0;
}

什么都没有打印出来

iMac-2$ ./a.out 
iMac-2:clang vik$

我搜索了一下,发现了这个:unicode hello world for C?

而且似乎我仍然需要设置一个语言环境(即使执行环境是 utf8?我仍在试图弄清楚为什么这一步是必要的)但无论如何,它有效! (经过一番挣扎,终于意识到正确的字符串是en_US.UTF-8,而不是我在某处读过的en_US.utf8……)

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

int main(){
  setlocale (LC_ALL, "en_US.UTF-8");
  wprintf(L"▒\n");
  return 0;
}

输出如下:

iMac-2$ ./a.out 
▒
iMac-2$

但是当我尝试以下代码时...输入 UTF-8 十六进制(我从这里得到:http://www.utf8-chartable.de/unicode-utf8-table.pl?start=9472&unicodeinhtml=dec),即 0xe29692 的盒子而不是粘贴盒子本身,它不起作用再次。

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

int main(){
  setlocale (LC_ALL, "en_US.UTF-8");
  wchar_t box = 0xe29692;
  wprintf(L"%lc\n", box);
  return 0;
}

我显然遗漏了一些东西,但无法弄清楚它是什么。

【问题讨论】:

  • 我应该注意,我正在使用以下编译器命令:cc --std=c11
  • 在 Mac OSX 上,您不需要 wchar.hwprintfL 前缀或 setlocale。如果你想打印一个盒子,就打印一个盒子:printf("▒\n");
  • @user3386109:它实际上取决于文本编辑器:它必须配置为将源文件保存为UTF-8
  • 使用setlocale(LC_ALL, ""); 设置默认语言环境。使用setlocale(LC_ALL, "C"); 设置C 语言环境。所有其他名称都是实现定义的。您的第二个示例在我的 Mac 上使用空字符串作为语言环境名称(就像使用您提供的全名一样)。我也可以肯定你的原始代码没有输出。

标签: c unicode utf-8


【解决方案1】:

MEDIUM SHADE 码位的 unicode 值不是0xe29692,而是0x2592&lt;E2&gt;&lt;96&gt;&lt;92&gt; 是 UTF-8 中此代码点的 3 字节编码。

您可以使用宽字符 API 打印此内容:

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

int main(void) {
    setlocale(LC_ALL, "en_US.UTF-8");
    wchar_t box = 0x2592;
    wprintf(L"%lc\n", box);  // or simply printf("%lc\n", box);
    return 0;
}

或者直接打印UTF-8编码:

#include <stdio.h>

int main(void) {
    printf("\xE2\x96\x92\n");
    return 0;
}

或者,如果您的文本编辑器将源文件编码为 UTF-8:

#include <stdio.h>

int main(void) {
    printf("▒\n");
    return 0;
}

但请注意,这不起作用:putchar('▒');

对于完整的 unicode 支持和更多好东西,我建议在 MacOS 上使用 iTerm2

【讨论】:

  • Mac Terminal.app 支持 Unicode 就好了;您甚至可以通过不同的配置文件选择要使用的编码。
  • @nneonneo: 是的,确实如此,但它过去不太完整,我使用iTerm2 的原因不同:它允许更多地控制重新映射修饰键,我经常使用它,尤其是当使用我自己的 emacs 版本在本地和远程编辑 ;-)
  • 哦,我现在明白了!谢谢! utf-8“编码”是一个最多 4 个字节的字符串,而不是一个 1 到 4 个字节的值。
  • 答案 #3 是正确的。如果您的编辑器不支持 UTF-8,那么您需要一个新的编辑器(是的,我知道,您已经使用它 30 年了——是时候开始使用现代工具了)。对于那些想知道为什么put char('▒’); 不起作用的人,这是因为它被设计为输出单个 ASCII 字节,而不是 UTF-8 字符(这是字节和字符让人困惑的地方)。
  • 我想我想知道 Unicode 的“不可移植性”是什么?只要看起来像字节,C 编译器就不会关心编辑器生成的内容。
【解决方案2】:

方框字符是 U+2592,在 UTF-8 中转换为 0xE2 0x96 0x92。您的第三个程序的这种改编主要适用于我:

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

int main(void)
{
    setlocale (LC_ALL, "en_US.UTF-8");
    wchar_t box = 0xe29692;
    wprintf(L"%lc\n", box);
    wprintf(L"\n\nX\n\n");
    box = L'\u2592'; //0xE2 0x96 0x92 = U+2592
    wprintf(L"%lc\n", box);
    wprintf(L"\n\n0x%.8X\n\n", box);
    box = 0x2592;
    wprintf(L"%lc\n", box);
    return 0;
}

我得到的输出是:

X

▒


0x00002592

▒

第一次打印操作没有任何用处;其他人工作。

在 Mac OS X 10.10.5 上进行测试。我碰巧正在使用 GCC 5.3.0(我编译过)进行编译,但使用 XCode 7.0.2 和 clang 得到了相同的输出。

【讨论】:

    猜你喜欢
    • 2013-02-03
    • 2017-10-05
    • 2015-03-14
    • 1970-01-01
    • 2013-11-23
    • 2013-06-01
    • 1970-01-01
    • 2021-10-20
    • 2021-12-26
    相关资源
    最近更新 更多