c++ - 向某些屏幕位置写入宽字符时,ncurses 会崩溃

标签 c++ linux unicode terminal ncurses

我正在使用 ncurses 编写一个应用程序,并希望在其中使用方框绘图字符,特别是 u/2550 和 u/2551(截至目前)。我有循环设置,根据我在其他地方确定的屏幕尺寸,在终端的两侧绘制条形图。

无论出于何种原因,当涉及到水平绘制任何 unicode 字符时(这里是在屏幕底部,但它在任何行上都这样做),它会从正常打印字符变成打印垃圾“P”。这有点难以解释,所以我有一些图片显示当我绘制 6 个字符然后绘制 7 个或更多字符时会发生什么。

With 6 characters

With 7 characters

负责绘制这些字符的代码部分是这样的,请注意最后一个 for 循环是绘制这些字符的部分,迭代器应该比 7 更远,但它在这里和其他任何地方都这样做。

void drawBorder(){ //draw the border graphics
                attron(COLOR_PAIR(3));
        for(int i = 1; i < screenSizeY - 1; i++){ //draw left side
                mvaddwstr(i, 0, L"║");
        }
        for(int i = 1; i < screenSizeY - 1; i++){ //draw right side
                mvaddwstr(i, screenSizeX - 1, L"\u2551");
        }
        for(int i = 0; i < 7; i++){ //draw bottom
                mvaddwstr(screenSizeY - 1, i, L"\u2550");
        }
                attroff(COLOR_PAIR(3));
}

我正在链接到 ncursesw 包,并且有一个正确设置的语言环境。其他用竖线画的字符也能正常工作,但这里不行。我正在使用用 g++ 编译的 C++,在 Linux 上的 Alacritty 终端 session 中运行。

这与画框功能或特定终端功能无关,终端完美支持所有宽字符,并在终端的其他部分工作。这将根据我在一行中绘制的这些字符的数量而发生,对于其他方框字符也会发生这种情况。

最佳答案

OP 发送了一个更完整的示例,它显示了问题:

#include <ncurses.h>
#include <string>
#include <iostream>

using namespace std;

int main(){

    initscr();
    setlocale(LC_ALL, "");
    raw();
    keypad(stdscr, TRUE);
    noecho();

    for(int i = 0; i < 10; i++){
        mvaddwstr(0, i, L"\u2550");
    }
    for(int i = 0; i < 6; i++){
        mvaddwstr(1, i, L"\u2550");
    }
    refresh();
    getch();
    endwin();

    return 0;

}

问题是库初始化时使用的语言环境与 mvaddwstr 调用中使用的语言环境不同。 manual page

The library uses the locale which the calling program has initialized. That is normally done with setlocale:

setlocale(LC_ALL, "");

If the locale is not initialized, the library assumes that characters are printable as in ISO-8859-1, to work with certain legacy programs. You should initialize the locale and not rely on specific details of the library when the locale has not been setup.

因为调用 setlocale 是在 initscr 之后,而不是之前,ncurses 假设数据是 ISO -8859-1,遇到意想不到的情况。在其他地方,例如 addwstr,ncurses 检查数据是否有效 wchar_t,但在那些地方,它使用的是当前 语言环境。在这种情况下,它远离它知道必须以这种方式处理的功能(它正在渲染已经处理过的数据)。允许使用 repeat_char 功能处理此问题的库中的比较可以改进,但实际错误在示例程序中。

关于c++ - 向某些屏幕位置写入宽字符时,ncurses 会崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54795303/

相关文章:

c++ - 将十进制转换为 32 位二进制?

python - 高效搜索大量 URL

linux - 将 perl 结果输出到文件中

linux - linux命令访问连接到嵌入式PC的USB内存棒?

c++ - 打印撇号 + 宽字符串文字破坏了我的 wofstream (C++)

python 3 : Demystifying encode and decode methods

php - Inpage urdu 到 unicode 乌尔都语转换器

c++ - 优化对指针 vector 的 new 调用?

c++ - 为什么反复调用clock_gettime时会看到400倍的异常时间?

c++ - 将 Lua 代码转换为 C++ 类并返回 C++