LINUX.ORG.RU

[СИ] Как узнать кодировку локали.

 


0

1

[СИ] Как узнать кодировку локали.

Язык СИ
ОС UNIX

Имеется самодельная СИ-программа. Она предназначена для работы
на машине-сервере в Дата-центре. Запускается через PuTTY.
Выдача программы должна быть на русском языке. Но ничего не
переключать вне этой программы.
В исходнике кодировка windows-1251. В программе есть перекодировщики
на koi8-r, utf-8.

На моем сервере и еще на двух других
опробована, там кодировка koi8-r. Работает, но я пока жестко
задал перекодировщик. Я слыхал, что некоторые работают на
других кодировках.

Вопрос-1.
Правильно ли я понимаю, что когда я подключаюсь через PuTTY,
то это моя локаль?

Вопрос-2.
Существует ли способ, чтоб программа узнала, какую кодировку
лучше выдать?

Кто знает прошу ответить.


> Правильно ли я понимаю, что когда я подключаюсь через PuTTY,

то это моя локаль?

???
При подключении в настройках Translation выставляйте CP1251 и в самой системе export LC_ALL=ru_RU.CP1251 и радуйтесь, если локаль сгенерирована.

Существует ли способ, чтоб программа узнала, какую кодировку

лучше выдать?


Запросто. Просто воспользуйтесь gettext при написании программы.
Если лень, смотрите из программы значения переменных окружения :
LANG
LANGUAGE
LC_CTYPE
LC_NUMERIC
LC_TIME
LC_COLLATE
LC_MONETARY
LC_MESSAGES
LC_PAPER
LC_NAME
LC_ADDRESS
LC_TELEPHONE
LC_MEASUREMENT
LC_IDENTIFICATION
LC_ALL

AITap ★★★★★
()

Локаль не твоя, твоей является только кодировка PuTTY.
Почитай man locale.h

arknir
()
Ответ на: комментарий от arknir

Ничего не понял.

Я не знаю что такое gettext.

Уточню вопрос.
Программа не для тиражирования, но ей все-таки будут пользоваться
разные люди. На разных машинах (UNIX). Поставит её человек (а всей
установки - положить файл и откомпилировать), и получит абракадабру.
А т. к. программа сама может разные кодировки выдавать, нельзя ли
сделать так, чтобы никаких настроек не менять, и сразу получить
хороший текст?

oleg_2
() автор топика

Вероятно, gettext — лучший вариант.

Но если хочется именно в программе держать константы на русском, то делаем так:

setlocale(LC_ALL, "");
const wchar_t msg[] = L"Привет, мир!";
wprintf(L"Сообщение: %ls\n", msg);

const86 ★★★★★
()
Ответ на: комментарий от Rubystar

> Почитал темы oleg_2. Какой упорный парень.

У тебя опечатки в слове «упоротый»

Led ★★★☆☆
()

Проще действительно воспользоваться gettext'ом. Это несложно, вначале делаем объявления макросов:

#define GETTEXT_PACKAGE "имя программы"
#define LOCALEDIR "путь к файлу с локалью (например, /usr/share/locale)"
#define _(String) gettext(String)
#define N_(String) String
В самом начале main() инициализируем gettext:
bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
textdomain(GETTEXT_PACKAGE);
Далее все строковые переменные пишем на английском, оформляя в «функции» _(). Те переменные, которые не должны переводиться сразу (например, инициализация массива), оформляем в «функции» N_(). Например:
char *errmsg[] = { // здесь в массив должны попасть англ. выражения,
// а перевод будет потом - поэтому используем N_()
N_("Too many markers")
,N_("Not enough markers")
,N_("Bad markers angle")
,N_("Too many rings")
};

...
g_err(_("Can't allocate memory for new spots")); // а здесь функция gettext должна вызываться сразу
...
Далее создаем из наших исходников .po-файл:
xgettext --from-code=koi8-r *.c -k_ -kN_ -o "имя .po-файла"
Полученный .po-файл переводим, строки там довольно простые и понятные интуитивно, например:
#: tracking.c:524
msgid "Bad amount of data points"
msgstr "Неверное количество точек с данными"
Только перевод лучше помещать в другой .po-файл (чтобы при повторном создании xgettext'ом не затереть перевод).

Чтобы при обновлении программы не вставлять новые строки вручную, добавляем их при помощи msgmerge:

msgmerge -Uis "переведенный .po-файл" "новый .po-файл"

Ну, а чтобы это все работало, в директорию, указанную в LOCALEDIR, надо поместить .mo-файл, который мы, после окончания перевода, генерируем командой

msgfmt ".po-файл с переводом" -o "результирующий .mo-файл"

Все это легко поддается автоматизации в Makefile'ах или cmake'ах.

В итоге от вас требуется лишь заполнить перевод и прогнать make еще раз.

// кроме того, вы получаете возможность выводить сообщения на нескольких языках, что довольно удобно, если вдруг программу потребуется куда-то еще отправлять

Eddy_Em ☆☆☆☆☆
()

[СИ] Как узнать кодировку локали.


nl_langinfo (CODESET)

akk ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.