我用Ruby开发游戏。它使用ncurses绘制窗口内容并刷新屏幕。这一切在macOS上都可以正常工作,我在那儿进行开发。但是在Linux上,从Ruby 或纯C 与ncurses接口时,除了纯ASCII外,我什么都无法打印。
例如,我得到以下输出:
Hello, world! M-b~U~TM-b~U~PM-b~U~WM-b~U~QM-b~U~QM-b~U~ZM-b~U~PM-b~U~]M-b~U~_M-b~T~@M-b~UM-"
而不是我输入的内容:
Hello, world! ╔═╗║║╚═╝╟─╢
文件编码为UTF-8,env
或locale
输出报告,LANG
和LC_*
变量在适当情况下为en_US
或en_US.UTF-8
。终端可以很好地打印这些字符,因此不是字体或终端仿真器设置。
Python 3也可以正常工作。 Ruby和C不会。
(在安装了libncurses5-dev
的全新Linux Mint 19安装程序上进行了测试。)
所以,我是否缺少某些设置,或者Python绑定有点特殊,我很走运吗?
它应该看起来像这样(macOS):
但是看起来确实像这样:
此代码可以正常工作:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import locale
import curses
locale.setlocale(locale.LC_ALL, '')
stdscr = curses.initscr()
curses.noecho()
curses.cbreak()
stdscr.addstr(0, 0, "╔═╗║║╚═╝╟─╢") # dont even need .encode('UTF-8')
stdscr.refresh()
stdscr.getkey()
curses.endwin()
curses模块的文档指出,自ncurses 5起,您必须执行此操作:https://docs.python.org/3/library/curses.html
从5.4版开始,ncurses库决定如何使用nl_langinfo函数解释非ASCII数据。这意味着您必须在应用程序中调用locale.setlocale()并使用系统可用的编码之一对Unicode字符串进行编码。
# coding: utf-8
require "curses"
Curses.init_screen
Curses.start_color
Curses.stdscr.keypad(true) # enable arrow keys
Curses.cbreak # no line buffering / immediate key input
Curses.ESCDELAY = 0
Curses.curs_set(0) # Invisible cursor
Curses.noecho # Do not print keyboard input
Curses.stdscr.addstr(STYLES[:single])
Curses.stdscr.setpos(2,0)
Curses.stdscr.addstr(%Q{╔═╗║║╚═╝╟─╢})
Curses.getch
尝试使用ffi-ncurses
宝石代替curses
,但无济于事。输出是相同的。
我用
进行编译gcc -finput-charset=UTF-8 -fexec-charset=UTF-8 -pedantic -Wall -o main main.c -lncurses
代码如下:
// Most of the code is sample code from "CURHELLO.C"
// (c) Copyright Paul Griffiths 1999
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <langinfo.h>
#include <locale.h>
#include <ncurses.h>
int main(void) {
// Here I tried to copy what Python is doing:
setlocale(LC_ALL, ""); // Also tried "C.UTF-8", "en_US.UTF-8"
nl_langinfo(CODESET);
WINDOW * mainwin;
if ( (mainwin = initscr()) == NULL ) {
fprintf(stderr, "Error initialising ncurses.\n");
exit(EXIT_FAILURE);
}
start_color();
clear();
cbreak();
noecho();
keypad(stdscr, TRUE);
mvaddstr(1, 1, "Hello, world! ╔═╗║║╚═╝╟─╢");
refresh();
sleep(3);
delwin(mainwin);
endwin();
refresh();
return EXIT_SUCCESS;
}
通过链接到ncursesw
(请注意结尾的W
)使其正常工作,但是在Linux上,它使用Ubuntu Mono(与我尝试过的相同字体)一起以文本宽度的两倍显示特殊字符。在OSX上使用iTerm。
答案 0 :(得分:2)
实际上这应该是几个问题,但是最近的一个问题询问如何将字符显示为全角。
屏幕截图与给定的示例程序不匹配。这只画了几个示例字符,而屏幕截图显示了方框。
但是,相对于语言环境表(并取决于所使用的 actual 程序),特定的画线字符可能是问题所在。这是因为这些代码是ambiguous width(请参阅U+2550)。该标准由实施者决定将其视为单角还是双角。并非所有人都同意实际宽度。
如果这是bug report,我将得到实际的程序源进行测试,但怀疑问题出在Ruby。