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

时间:2016-02-02 20:12:54

标签: c ascii ncurses

我有这个程序:

:inoremap # X^H#

当ncurses打印出第一个单词(ñandñ)时会发生一些事情,当之后移动到另一个位置时(在这种情况下为1,34),实际上它会移动到另一个位置,所以第二个单词会在另一个列中打印出来。

那应该是什么样的:

#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;
}

看起来像这样:

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

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

知道出了什么问题吗? 谢谢!

1 个答案:

答案 0 :(得分:4)

如果要使用多字节UTF-8字符,则必须使用以多字节支持编译的ncurses库版本,并且需要在程序开头正确设置区域设置。

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

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

就足够了
setlocale(LC_ALL, "");

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

#include <locale.h>

到你的标题包括。不需要链接特殊库来支持语言环境。

原始问题表明正在使用mvaddwstr。这通常是多字节字符的更好解决方案,但如上所述,您可以根据需要使用窄字符串接口。但是,您不能输出不完整的UTF-8序列,因此像addch这样的单字符窄接口只能用于小于128的字符代码。

此说明适用于尝试使用mvaddwstr而不是char*参数调用wchar_t*。不要这样做:

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