未在Ruby中打印的Unicode框图字符 [英] Unicode Box Drawing characters not printed in Ruby
问题描述
我用Ruby开发游戏.它使用ncurses绘制窗口内容并刷新屏幕.在macOS上,所有这些都可以正常工作,我在那儿进行开发.但是在Linux上,当从Ruby 或纯C 与ncurses接口时,除了纯ASCII外,我什么都无法打印.
I work on a game in Ruby. It uses ncurses to draw window contents and refresh the screen. This all works fine on macOS, where I develop the stuff. But on Linux, I cannot get anything besides plain ASCII to print when interfacing with ncurses either from Ruby or plain C.
例如,我得到以下输出:
For example, I get this output:
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
.终端可以很好地打印这些字符,因此不是字体或终端仿真器设置.
File encoding is UTF-8, env
or locale
output reports LANG
and LC_*
variables to be en_US
or en_US.UTF-8
where appropriate. The terminal can print these characters just fine, so it's not the font or terminal emulator setting.
Python 3也可以正常工作. Ruby和C不会.
Python 3 works fine, too. Ruby and C don't.
(在安装了libncurses5-dev
的全新Linux Mint 19安装程序上进行了测试.)
(Tested on a fresh Linux Mint 19 setup with libncurses5-dev
installed.)
所以,我是否缺少某些设置,或者Python绑定有点特殊,我很走运吗?
它应该看起来像这样(macOS):
It should look like this (macOS):
但是确实看起来像这样:
But does look like this instead:
此代码可以正常工作:
#!/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
The docs for the curses module state that you have to do this since ncurses 5: https://docs.python.org/3/library/curses.html
从5.4版开始,ncurses库决定如何使用nl_langinfo函数解释非ASCII数据.这意味着您必须在应用程序中调用locale.setlocale()并使用系统可用的编码之一对Unicode字符串进行编码.
Since version 5.4, the ncurses library decides how to interpret non-ASCII data using the nl_langinfo function. That means that you have to call locale.setlocale() in the application and encode Unicode strings using one of the system’s available encodings.
Ruby代码
# 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
,但无济于事.输出是相同的.
Tried with the ffi-ncurses
gem instead of curses
but to no avail. The output is the same.
我用
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在UNIX上以文本宽度的两倍显示特殊字符,这与我在OSX上使用iTerm尝试的相同字体
Edit
Got it working by linking to ncursesw
(note the trailing W
!), but it displays the special characters at double the width of text on Linux, using Ubuntu Mono, the same font I tried on OSX with iTerm.
推荐答案
实际上这应该是几个问题,但是最近的一个问题是如何将字符显示为全角.
Actually this should be several questions, but the most recent one asks how the characters could be shown as double-width.
屏幕截图与给定的示例程序不匹配.这样只画了几个示例字符,而屏幕截图显示了方框.
The screenshot does not match the given example program. That only draws a few sample characters, while the screenshot shows boxes.
但是,相对于语言环境表(并取决于所使用的 actual 程序),特定的画线字符可能是个问题.那是因为这些代码是 歧义宽度 (请参见 U + 2550 ).该标准由实施者决定将其视为单角还是双角.并非所有人都同意实际宽度.
However, the particular line-drawing characters can be the problem, versus the locale tables (and depending on the actual program used). That's because those codes are ambiguous width (see U+2550). The standard leaves it up to the implementer whether to treat them as single-width or double-width. Not everyone agrees on the actual width.
如果这是错误报告,我会得到实际的程序源进行测试,但怀疑问题出在Ruby.
If this were a bug report, I'd get the actual program source to test with, but suspect the problem lies in Ruby.
这篇关于未在Ruby中打印的Unicode框图字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!