如何确保使用NCURSES的终端支持Unicode/宽字符?

5
我正在开发一个NCURSES应用程序,用于进行小型TUI(文本用户界面)练习。不幸的是,我没有使用万能的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 上运行程序时,我需要抛出错误。


请注意,新行序列为\r\n而不是\n\r,但在C中您不需要考虑这个问题,因为C运行时会自动将其转换为正确的新行符号。 - phuclv
3个回答

2
正如所述,您无法可靠地检测终端的功能。实际上,您也不能检测终端对颜色的支持。在任一情况下,您的应用程序只能检测您已配置的内容,这并不相同。
有些人通过编写一个UTF编码字符,并使用光标位置报告来查看光标位置(例如,参见Detect how much of Unicode my terminal supports, even through screen)来部分成功地检测Unicode支持。
编译/链接使用ncursesw需要正确配置您的语言环境,并针对某些不支持UTF-8模式下VT100行图形的终端(如PuTTY)进行一些解决方法。
更多阅读:

1
您无法做到。ncurses(w)使用termcap来确定终端的能力,并查看$TERM环境变量以确定正在使用哪个终端。没有特殊的该变量值指示终端支持Unicode;XTerm和UXTerm都设置TERM=xterm。许多其他终端应用程序也使用该值的$TERM,包括支持Unicode和不支持Unicode的应用程序。(实际上,在许多终端模拟器中,可以在运行时启用和禁用Unicode支持。)
如果您想开始向终端输出Unicode文本,您只需相信用户的终端将支持它。
但是,如果您只想输出框图字符,则可能根本不需要Unicode——这些字符作为VT100图形字符集的一部分可用。您可以在ncurses应用程序中使用ACS_*常量(例如,ACS_ULCORNER用于┌),或使用类似box()的函数为您绘制一个更大的图形。

0

nl_langinfo() 函数将返回一个指向包含与当前语言环境或文化区域相关的信息的字符串的指针。

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

bool supportsUnicode()
{
        /* Set a locale for the ctype and multibyte functions.
         * This controls recognition of upper and lower case,
         * alphabetic or non-alphabetic characters, and so on.
         */
        setlocale(LC_CTYPE, "en_US.UTF-8");
        return (strcmp(nl_langinfo(CODESET), "UTF-8") == 0) ? true : false;
}

请参考htop源代码,该代码可以绘制带有/不带有Unicode的线条。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接