未在Ruby中打印的Unicode框图字符 [英] Unicode Box Drawing characters not printed in Ruby

查看:80
本文介绍了未在Ruby中打印的Unicode框图字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用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,envlocale输出报告,LANGLC_*变量在适当的情况下为en_USen_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆