当将宽字符写入某些屏幕位置时,ncurses会变得烦躁不安

问题描述 投票:3回答:1

我正在使用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 ++,在Alacritty终端会话中在Linux上运行。

这与盒子绘制功能或特定终端功能无关,终端完全支持所有宽字符,并在终端的其他部分工作。这将基于我连续绘制了多少这些,以及其他框字符也会发生。

c++ linux unicode terminal ncurses
1个回答
5
投票

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

该库使用调用程序初始化的语言环境。这通常是用setlocale完成的:

setlocale(LC_ALL, "");

如果未初始化语言环境,则库假定字符可按ISO-8859-1打印,以使用某些旧程序。您应该初始化语言环境,而不是在未设置语言环境时依赖库的特定详细信息。

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

© www.soinside.com 2019 - 2024. All rights reserved.