我刚刚编写了一个 C++] 程序,它使用方框字符来显示信息。我在 macOS 上运行了该程序并使用了终端应用程序,它运行得很好。
当我切换到Debian Linux使用相同的代码并重新编译它,我才遇到这个问题!我在网上搜索了答案,但没有找到与这个问题相关的答案。我已经用两者测试过这个LX终端和 URXVT。
这是这个问题的最小可重现示例:
#include <ncurses.h>
#include <iostream>
int ch;
int main() {
setlocale(LC_CTYPE, "");
initscr();
noecho();
keypad(stdscr, true);
nodelay(stdscr, true);
curs_set(0);
start_color();
use_default_colors();
init_pair(1, COLOR_BLUE, -1);
clear();
refresh();
while ((ch = getch()) != 'q' && ch != 'Q') {
attrset(COLOR_PAIR(1));
mvprintw(0,0,"┏━┓");
mvprintw(1,0,"┗━┛");
}
refresh();
endwin();
return 0;
}
使用以下命令编译此演示:
g++ -g -c -o main.o test.cpp && g++ -g -o test main.o -std=c++11 -Wall -pedantic -lncurses
或者
LDLIBS=-lncurses make test
而不是显示
┏━┓
┗━┛
它显示这个:
M-b~T~OM-b~T~AM-b~T~S
M-b~T~WM-b~T~AM-b~T~[
实际屏幕图像
macOS 上的正常(所需)显示:
Linux下显示异常:
答案1
问题是您使用的是文字字符┌
, ─
, ┐
, └
, ─
,┘
而不是使用ncurses
独立的符号。您应该使用ACS_??CORNER
(U
pper/ L
ower 和L
eft/ R
ight)和ACS_HLINE
符号名称,并让ncurses
我们弄清楚如何在终端上表示这些名称。
从此修改您的代码,
mvprintw(0,0,"┏━┓");
mvprintw(1,0,"┗━┛");
对此,
move(0,0); addch(ACS_ULCORNER); addch(ACS_HLINE); addch(ACS_URCORNER);
move(1,0); addch(ACS_LLCORNER); addch(ACS_HLINE); addch(ACS_LRCORNER);
应确保代码可移植地工作。我还将程序的结尾main()
从简单的更改return 0
为以下内容,以便在程序结束时正确重置终端:
endwin();
exit(0);
编译test.cpp
并执行,
LDLIBS=-lncurses make test && ./test
有用的参考资料,排名不分先后:
答案2
在 MacOS 上,-lncurses
ncurses 的宽字符配置的链接通常由-lncursesw
.该setlocale
调用给出了不同的结果(正常字符与宽字符),并且框字符的文字字符串(UTF-8)的结果也不同。
进一步阅读:
- Curses 库在 OS X High Sierra 上不支持宽字符,为了我的解释
- 替代配置在 ncurses 手册中
- 键名,其扩展为取消控制和添加,注意到
- 大于 128 的值要么是元字符(如果屏幕尚未初始化,或者使用 TRUE 参数调用了 meta(3x)),如MX符号,或显示为它们自己。在后一种情况下,这些值可能无法打印;这遵循 X/Open 规范。
根本问题是盒字符的 UTF-8 编码使用高于 128 的字节码,并且如果没有宽字符库中使用的区域设置支持,您将得到这样的结果 — 无法将字节重新组装成宽字符。特点。
其他一些平台也-lncurses
作为 的别名出现-lncursesw
,例如(注意注释)Arch Linux,其中有/usr/lib/ncurses.so
:
INPUT(-lncursesw)
另一条评论询问了“粗线”。这里有几点:
- 在我的回答中双行box_在终端中绘制字符,我提到ncurses提供了符号以方便使用Unicode厚的和双倍的线。
- 那些已经在 ncurses 中了2009年10月:
出于通常的原因,我只实现了粗线/双线的 WACS_xxx 符号:它是实验性的,并且仅对 Unicode 有用。
- 这些符号记录在
wadd_wch
手册页。 - 该功能不适用于 MacOS 的捆绑 ncurses,因为该版本(ncurses 5.7)比 ncurses 的更改早了大约一年。
- 它不适用于 Linux 控制台终端(因为它依赖于只有 512 个字形的字体)。
- 实际上外貌粗/双线的数量未指定(这取决于字体)。
答案3
问题是方框字符在 Linux 终端中无法正确显示。解决方案是您需要以不同的方式编译代码。
如果您正在使用printw
ncurses 或其他一些使用 ncurses 作为库的文本显示方法,那么这将适用于您。这取决于操作系统,因此如果您在 macOS 上,您将 -lncurses
在编译时使用该标志(也根据@terdon,这也适用于架构Linux,但我还没有测试过),如果你使用的是 Linux(我只测试过 Debian),你需要使用该-lncursesw
标志。
如果您想自动使您的代码交叉兼容此问题,请将其放入您的 makefile 中。
ifneq ($(OS),Windows_NT)
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
NCURSES += -lncursesw
endif
ifeq ($(UNAME_S),Darwin)
NCURSES += -lncurses
endif
endif