无法在 NCURSES 中正确打印扩展 ASCII 字符

Cannot correctly print extended ASCII characters in NCURSES

我有这个程序:

#include <ncurses.h>
int main () {
    initscr();
    mvaddstr(0, 0, "              A         B         C         D         E       ");
    mvaddstr(1, 24, "ñandñ");
    mvaddstr(1, 34, "esdrñjulñ");
    refresh();
    getch();
    endwin();
    return 0;
}

当 ncurses 打印第一个单词 (ñandñ) 之后移动到另一个位置(在本例中为 1、34)时,实际上它移动到另一个位置,因此第二个单词被打印在另一列中。

那么它应该是什么样子:

          A         B         C         D         E       
                              ñandñ     esdrñjulñ

看起来像这样:

          A         B         C         D         E       
                              ñandñ   esdrñjulñ

因为第一个单词中有两个 'ñ' 扩展 ascii 字符。

知道哪里出了问题吗? 谢谢!

如果你想使用多字节的UTF-8字符,你必须使用编译时支持多字节的ncurses库版本,并且你需要在你的程序开始时正确设置语言环境。

多字节 ncurses 库通常称为 libncursesw,因此要使用它就足以在您的链接器选项中将 -lncurses 更改为 -lncursesw。您不需要不同的 header 文件。但是,如果您真的想使用 wide-character 函数,则必须在任何 #include 指令之前 #define 符号 _XOPEN_SOURCE_EXTENDED。使用 gcc(或 clang)执行此操作的最简单方法是将 -D_XOPEN_SOURCE_EXTENDED 添加到您的编译器选项。

如果您的 shell 语言环境已设置为 UTF-8 语言环境(现代 Linux 发行版通常是这种情况),插入

setlocale(LC_ALL, "");

在调用 ncurses 例程之前。这会将可执行文件的语言环境设置为由环境变量配置的语言环境。您需要添加

#include <locale.h>

您的 header 包含。无需链接特殊库即可获得语言环境支持。


最初的问题表明正在使用 mvaddwstr。这通常是多字节字符的更好解决方案,但如上所示,如果需要,您可以使用窄字符串接口。但是不能输出不完整的UTF-8序列,所以像addch这样的single-character窄接口只能用于小于128的字符编码。

此注释适用于使用 char* 而不是 wchar_t* 参数调用 mvaddwstr 的尝试。不要那样做:

像所有接受字符串的 w ncurses 函数一样,mvaddwstrwchar_t* 作为其字符串参数。你的编译器应该已经警告过你(除非它警告过你 mvaddwstr 没有原型)。所以字符串应该以 L 长度属性为前缀:L"ñandñ".