[Решено] Проблемы с кодировкой (ncurses) (при переносе Lubuntu -> Gentoo)

Модератор: Модераторы разделов

Аватара пользователя
Ater
Сообщения: 50
ОС: GNU/Linux

[Решено] Проблемы с кодировкой (ncurses)

Сообщение Ater »

Доброго дня всем.
Возникла проблема с переносом софта из Lubuntu в Gentoo. Есть некая самописная прога, использующая ncurses. Под *бунтой все работает как должно. При компиляции в генте все норм, но при запуске вместо русских букв лезет черт знает что. Набросал быстренько тестовую прогу, вот код:

Код: Выделить всё

#include <ncursesw/curses.h>
#include <locale.h>

int main(int argc, char **argv)
{
	printf("%s\n", setlocale(LC_ALL, ""));
	initscr();
	printw("==Тест==");
	refresh();
	getch();
	endwin();
	return 0;
}
При компиляции/запуске без setlocale() (printf() только для того, чтобы видеть выхлоп) результат одинаков в обоих системах - часть букв отображается нормально, часть нет.
С setlocale() в *бунту все в порядке, в генте - ни фига, абсолютно все рус. буквы превращаются в кашу, из 4 символов получается последовательность в 22 байта. Символы "=" вставил именно для определения начала и конца нужной последовательности при перенаправлении вывода в файл.
Проверял в голом консольном (текст 80х25) режиме, в терминалах xterm и st - результат абсолютно одинаков.
Вместо ncursesw/curses.h (это *бунтовый вариант, просто файла /usr/include/curses.h там нет) изначально пробовал просто curses.h, разницы абсолютно никакой.
Стандартный ввод/вывод работает нормально, кодировка utf-8, шрифт cyr-sun16 использую, проблем никаких не возникало до сих пор.
Понимаю, что проблема связана с кодировкой/локалью. Гугление и яндексование упорно отсылает к функции setlocale(), но это было сделано сразу при написании.

Был бы очень благодарен за любые подсказки.
Извините, если несколько несвязно изложил мысли.
Последний раз редактировалось Ater 14.01.2023 13:20, всего редактировалось 1 раз.
Спасибо сказали:
Аватара пользователя
olecya
Сообщения: 776
ОС: debian, fedora (i3-wm)

Re: Проблемы с кодировкой (ncurses)

Сообщение olecya »

А библиотеку подключаете при компиляции -lncurses или -lncursesw ?
Спасибо сказали:
Аватара пользователя
Ater
Сообщения: 50
ОС: GNU/Linux

Re: Проблемы с кодировкой (ncurses)

Сообщение Ater »

Да, совсем забыл этот момент указать, хотя пробовал тоже. Подключаю -lncurses, при -lncursesw компилится, но при запуске падает сразу с ошибкой сегментирования.
Вот, тоже забыл сказать, выхлоп printf("%s\n", setlocale(LC_ALL, "")); --> ru_RU.utf8
Спасибо сказали:
Аватара пользователя
olecya
Сообщения: 776
ОС: debian, fedora (i3-wm)

Re: Проблемы с кодировкой (ncurses)

Сообщение olecya »

Я не гентушница. В федоре компилирую с -lncurses и с заголовочным файлом #include <curses.h> получаю:
==M-PM-"M-PM-5M-Q~AM-Q~B==
В библиотеке с широкими символами все работает нормально и компилируется и запускается. Включите -Wall -Wextra может что вылезет.
После компиляции вашего примера в двух вариантах получаю:

Код: Выделить всё

ldd ./tost
	linux-vdso.so.1 (0x00007ffebdfd4000)
	libncurses.so.6 => /lib64/libncurses.so.6
        ...
и соответственно:

Код: Выделить всё

ldd ./tost
	linux-vdso.so.1 (0x00007fffa8fad000)
	libncursesw.so.6 => /lib64/libncursesw.so.6
	...
Вывод команды в терминале:

Shell

locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
Спасибо сказали:
Аватара пользователя
Ater
Сообщения: 50
ОС: GNU/Linux

Re: Проблемы с кодировкой (ncurses)

Сообщение Ater »

olecya
Проблема решена, и моё Вам огромное благодарственное мяу!

Проблема была в моей невнимательности и поспешности. С с -lncurses и с заголовочным файлом #include <curses.h> у меня были точно те же самые загадочные письмена ==M-PM-"M-PM-5M-Q~AM-Q~B==
Все дело в неверных ключах компиляции. Не знаю, как в федоре, но в генте от ncurses отделили tinfo, т.е. надо указывать так: -lncurses -ltinfo, либо так: -lncursesw -ltinfow для широких. А я-то все скрещивал ежа с ужом посредством -lncursesw -ltinfo :D

Выхлоп ldd для правильного варианта с wide:

Код: Выделить всё

	linux-gate.so.1 (0xb7f7a000)
	libncursesw.so.6 => /lib/libncursesw.so.6 (0xb7f26000)
	libtinfow.so.6 => /lib/libtinfow.so.6 (0xb7eec000)
	libc.so.6 => /lib/libc.so.6 (0xb7cdd000)
	/lib/ld-linux.so.2 (0xb7f7c000)
Выхлоп для моего неправильного:

Код: Выделить всё

	linux-gate.so.1 (0xb7f7b000)
	libncursesw.so.6 => /lib/libncursesw.so.6 (0xb7f27000)
	libtinfo.so.6 => /lib/libtinfo.so.6 (0xb7eef000)
	libc.so.6 => /lib/libc.so.6 (0xb7ce0000)
	libtinfow.so.6 => /lib/libtinfow.so.6 (0xb7ca6000)
	/lib/ld-linux.so.2 (0xb7f7d000)
Разница очевидна. И я еще удивлялся, чего оно крашится... Сам виноват. Внимательнее надо быть, и не торопиться.
Правильный ответ: #include <curses.h> и gcc траляля -lncursesw -ltinfow
Спасибо сказали: