繁体   English   中英

ncurses如何输出非ASCII字符?

[英]How does ncurses output non-ascii characters?

我想知道ncurses(ac库)如何将字符放入,尽管(据我所知)它们并不是ASCII的一部分。

我本以为只是按像素绘制它们,但是您可以将它们复制/粘贴到终端之外(在MacOS中)。

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(1970年代末)和AT&T 4410和5410终端(显然是1980年代以来的早期)所使用的转义序列来实现。后者在1984年被用来绘制其图形字符。
  • AT&T SystemV curses从1980年代中期开始为这些图形字符提供支持。 BSD的诅咒从未做到过...
  • Unicode(大约在1990年及以后)使用不同的编码提供了大多数相同的字形 有一些遗漏(最引人注意的是扫描线用于水平线的上方/下方),但是一旦UTF-8在2000年代初投入使用,就可以合理地扩展ncurses来使用这些字符。
  • ncurses会查看语言环境设置,但更喜欢对这些图形字符使用终端说明,除非已知情况不起作用,并且假定该终端可以使用UTF,则假定该终端可以显示这些字符的Unicode等效项。 -8。 为此,它使用了一个表(SystemV诅咒及其后继X / Open Curses并没有执行任何操作-NetBSD诅咒从2010年以后的某个时候改写了ncurses的表)。

进一步阅读:

ncurses的版本不止一个,且平台不止一个,如果您真的想知道,请查看源代码。 但是,它们都不会逐个像素地绘制一个字符。 那不是在终端仿真器中运行的库所要做的。

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

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

如果程序关心本地多字节编码不是UTF-8的系统的可移植性,则可以使用其他库(例如C ++标准库或ICU)在UTF-8和宽字符字符串之间进行转换,然后显示带有curses的字符串。

您可能需要#define _XOPEN_SOURCE 700或目标标准版本的适当值,并且对于某些版本的库,还需要#define _XOPEN_SOURCE_EXTENDED 1 ,以使系统库允许使用诸如addwstr之类的功能()

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

暂无
暂无

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

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