Я работаю над игрой в Ruby.Он использует ncurses для рисования содержимого окна и обновления экрана.Все это прекрасно работает на macOS, где я разрабатываю материал.Но в Linux я не могу получить ничего, кроме простого ASCII, для печати при взаимодействии с ncurses из Ruby или простого C .
Например, я получаю такой вывод:
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 этого не делают.
(протестировано на новой установке Linux Mint 19 с установленным libncurses5-dev
.)
Итак, Я пропустил некоторые настройки или это привязка Pythonчто-то особенное, и мне не повезло?
Как это выглядит
Это должно выглядеть так (macOS):
Но вместо этого выглядит так:
Код Python
Этот кодработает просто отлично:
#!/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 решаеткак интерпретировать данные не ASCII, используя функцию nl_langinfo.Это означает, что вам нужно вызвать locale.setlocale () в приложении и кодировать строки Unicode, используя одну из доступных системных кодировок.
Ruby Code
# 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
, но безрезультатно.Вывод такой же.
C Код
Я компилирую с
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.