我如何保证终端具有 NCURSES 的 Unicode/wide 字符支持?

How could I guarantee a terminal has Unicode/wide character support with NCURSES?

我正在为一些 TUI(文本用户界面)练习开发 NCURSES 应用程序。不幸的是,我没有使用曾经如此美妙和忠实的 ASCII 的选项。我的程序使用了很多 Unicode 方框绘图字符。

我的程序已经可以检测终端是否支持颜色。我需要做类似的事情:

if(!supportsUnicode()) //I prefer camel-case, it's just the way I am.
{
    fprintf(stderr, "This program requires a Unicode-capable terminal.\n\r");
    exit(1);
}
else
{
    //Yay, we have Unicode! some random UI-related code goes here.
}

这不仅仅是包含 ncursesw 和设置语言环境的问题。我需要获取特定的终端信息,如果它不会发生,我实际上会抛出一个错误。例如,当用户尝试 运行 可爱 XTerm 中的程序而不是支持 Unicode 的 UXTerm.

时,我需要抛出错误

你不能。 ncurses(w) 使用 termcap 来确定终端具有哪些功能,并查看 $TERM 环境变量以确定正在使用的终端。该变量没有特殊值表明终端支持 Unicode; XTerm 和 UXTerm 都设置 TERM=xterm。许多其他终端应用程序也使用 $TERM 的值,包括支持 Unicode 和不支持 Unicode 的应用程序。 (实际上,在许多终端仿真器中,可以在运行时启用和禁用 Unicode 支持。)

如果您想开始向终端输出 Unicode 文本,您只需相信用户的终端会支持它。

如果您只想输出方框绘图字符,那么您可能根本不需要 Unicode — 这些字符作为 VT100 图形字符集的一部分可用。您可以使用 ACS_* 常量在 ncurses 应用程序中输出这些字符(例如,ACS_ULCORNER 表示 ),或者使用 box() 之类的函数为您绘制更大的图形.

如前所述,您无法可靠地检测终端的功能。就此而言,您也无法检测到终端对颜色的支持。无论哪种情况,您的应用程序只能检测您配置的内容,这不是一回事。

有些人通过编写一个 UTF 编码的字符并使用光标位置报告来查看光标所在的位置来部分成功地检测到 Unicode 支持(参见示例 Detect how much of Unicode my terminal supports, even through screen).

Compiling/linking 与 ncursesw 依赖于正确配置您的语言环境,并为终端(例如 PuTTY)提供一些解决方法,这些终端在处于UTF-8 模式。

进一步阅读:

nl_langinfo() 函数应 return 一个指向字符串的指针,该字符串包含与当前语言环境中定义的特定语言或文化区域相关的信息。

#include <langinfo.h>
#include <locale.h>
#include <stdbool.h>
#include <string.h>

bool supportsUnicode()
{
        setlocale(LC_CTYPE, "");
        return strcmp(nl_langinfo(CODESET), "UTF-8") ? false : true;
}

参考htop可以画线的源代码with/without Unicode。