ncurses如何输出非ascii字符?

时间:2017-04-28 03:47:40

标签: c ncurses

我想知道ncurses(一个c库)如何设置像这样的字符,尽管它们(据我所知)不是ASCII的一部分。

我原以为它只是逐个像素地绘制它们,但你可以将它们复制/粘贴到终端之外(在MacOS中)。

2 个答案:

答案 0 :(得分:3)

ncurses通过假设您的区域设置环境变量( LC_ALL 和/或 LC_CTYPE )匹配,将├等字符放在屏幕上您正在显示的终端。环境变量指示编码(例如,UTF-8)。还有其他编码和终端支持这些编码,但一般来说你大多看到UTF-8。如果环境和终端合作,那么事情就是工作":

  • 在启动时,ncurses通过setlocale检查程序初始化的语言环境,并确定是否使用UTF-8。它稍后会使用该信息。
  • 当程序添加字符串时,例如,使用addstr,ncurses使用字符类型信息(设置为调用setlocale的副作用),并使用标准C库函数进行组合构成多字节字符的字节序列,并将它们转换为宽字符。它在内部存储那些宽字符,
  • 写入终端时,ncurses会反转进程,从宽字符转换为使用终端支持的编码假设(假设您的语言环境与终端匹配)。

但是 -

表示 的字符恰好是特例。这是用于线条绘制的图形字符之一,它早于Unicode和UTF-8。 curses具有这些图形字符的名称,使其易于引用,例如 ACS_LTEE 是左图) :

  • 在UTF-8出现问题之前,开发人员通过调整用于VT100(20世纪70年代后期)以及AT& T 4410和5410终端的转义序列(显然使用这些图形字符的表格)提出了一个方案。 20世纪80年代初,因为后者在1984年被用于绘制他们的图形角色。
  • AT& T SystemV curses从20世纪80年代中期开始为这些图形字符提供支持。 BSD诅咒从未这样做过......
  • Unicode(大约1990年及以后)使用不同的编码提供了大多数相同的字形。有一些遗漏(最引人注目的是扫描线高于/低于用于水平线的那条线),但是一旦UTF-8在21世纪初投入使用,扩展ncurses是合乎逻辑的。使用这些字符。
  • ncurses查看区域设置,但更喜欢使用这些图形字符的终端描述,除非已知不起作用的情况 - 并且假设终端可以显示Unicode等效项如果假设终端使用UTF-8,则为这些字符。它为此目的使用了一个表(SystemV curses及其后继者X / Open Curses没有做任何这些 - NetBSD curses在2010年后的某个时候从ncurses中调整了表格。)

进一步阅读:

答案 1 :(得分:0)

对于多个平台,有多个版本的ncurses,如果您真的想知道,请查看源代码。但是,它们都不会逐个像素地绘制字符;这不是在终端模拟器中运行的库所做的事情。

C标准库的现代版本,POSIX和ncurses都支持将宽字符写入控制台以及在宽字符串和多字节字符串之间进行转换。今天,宽字符通常是UTF-16或UTF-32,多字节字符串通常是UTF-8。您可以查看<wchar.h>和ncursesw的文档以获取更多信息。

请注意,C11通过u8前缀确实支持UTF-8文字。

关注本地多字节编码不是UTF-8的系统的可移植性的程序可以使用另一个库(如C ++标准库或ICU)在UTF-8和宽字符字符串之间进行转换,然后显示那些诅咒。

您可能需要#define _XOPEN_SOURCE 700,或者您要定位的标准版本的相应值,以及某些版本的库#define _XOPEN_SOURCE_EXTENDED 1,以使您的系统库能够让您使用functions such as addwstr()

但是,许多程序可能只是将以UTF-8编码的char字符串发送到控制台并假设它可以处理它们。我不推荐这种方法,但它适用于2017年的大多数Linux系统。