- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Linux программирование в примерах - Арнольд Роббинс
Шрифт:
Интервал:
Закладка:
Таблица 13.4. Компоненты спецификации эры
Компонент Значение Направление Символы '+' или '-'. '+' означает, что эра отсчитывается от численно меньшего года к численно большему году, а '-' означает обратный порядок Смешение Ближайший к дате начала эры год Дата начала Дата начала эры в виде 'гггг/мм/дд'. Это соответственно год, месяц и день. Годы до н.э используют для гггг отрицательные значения Дата конца Дата завершения эры в том же самом виде. Допустимы два дополнительных вида: -* означает «начало времени», а +* означает «конец времени» Название эры Название эры, соответствующее спецификации преобразования %EC функции strftime() Формат эры Формат года в пределах эры, соответствующий спецификации преобразования %EY функции strftime()Значение ALT_DIGITS также нуждается в некотором объяснении. Некоторые локали предоставляют «альтернативные цифры». (Рассмотрите арабский язык, в котором используется десятичная система счисления, но изображения для цифр 0–9 другие. Или рассмотрите гипотетическую локаль «Древнего Рима», использующую римские цифры.) Они появляются, например, в различных спецификациях преобразования %OC в функции strftime(). Возвращаемое значение для 'nl_langinfo(ALT_DIGITS)' является разделяемым точками с запятой списком строк символов для альтернативных цифр. Первая должна использоваться для 0, следующая для 1 и т.д. POSIX утверждает, что могут быть предоставлены до 100 альтернативных символов. Сущность в том, чтобы избежать ограничения локалей использованием символов цифр ASCII, когда у локали есть собственная система счисления.
Наконец, 'nl_langinfo(CRNCYSTR)' возвращает символ местной валюты. Первый символ возвращаемого значения, если это '-', '+' или '.', указывает, как должен использоваться символ:
- Символ должен быть перед значением.
+ Символ должен быть после значения.
. Символ должен заменить символ основания (разделитель десятичной дроби).
13.3. Динамический перевод сообщений программ
Только что освещенные интерфейсы стандартной библиотеки С решают простые части проблемы локализации. Для денежных, числовых значений, значений времени и даты, также, как для проблем сортировки строк, применяется управление посредством таблиц специфичных для локали данных (таких, как списки названий месяцев и дней).
Однако, большая часть взаимодействия пользователя с текстовой программой осуществляется в виде выводимых сообщений, таких, как приглашения или сообщения об ошибках. Проблема заключается в необходимости избежания множества версий одной и той же программы, которые отличаются лишь содержанием строк сообщений. Решением де-факто в мире GNU является GNU gettext. (GNU программы сталкиваются с подобными проблемами с элементами меню; обычно у каждого большого инструментария пользовательского интерфейса свой способ решения этой проблемы.)
GNU gettext дает возможность перевода сообщений программы на другие языки во время исполнения. Внутри кода программы этот перевод включает несколько шагов, каждый из которых использует свои библиотечные функции. Когда сама программа должным образом подготовлена, несколько утилит на уровне оболочки дают возможность подготовить переводы на другие языки. Каждый такой перевод называется списком сообщений (message catalog).
13.3.1. Установка текстового домена: textdomain()
Законченное приложение может содержать множество компонентов: отдельные исполняемые файлы, написанные на С или C++ или на языках сценариев, которые также могут получить доступ к возможностям gettext, таких, как gawk или оболочка Bash Все компоненты приложения разделяют один и тот же текстовый домен, который является строкой, уникально идентифицирующей приложение. (Примерами могут быть «gawk» или «coreutils»; первое является простой программой, а последнее — целым набором программ.) Текстовый домен устанавливается функцией textdomain():
#include <libintl.h> /* GLIBC */
char* textdomain(const char *domainname)
Каждый компонент должен вызывать эту функцию со строкой, указывающей на текстовый домен, в составе первоначальной инициализации в main(). Возвращаемое значение является текущим текстовым доменом. Если аргумент domainname равен NULL, возвращается текущий домен; в противном случае, он устанавливается в указанное значение, а последнее возвращается. Возвращаемое значение NULL указывает на какую-нибудь разновидность ошибки.
Если текстовый домен не установлен с помощью textdomain(), по умолчанию используется «messages».
13.3.2. Перевод сообщений: gettext()
Следующим после установки текстового домена шагом является использование функции gettext() (или ее разновидности) для каждой строки, которая должна быть переведена. Несколько функций предоставляют службы перевода:
#include <libintl.h> /* GLIBC */
char *gettext(const char *msgid);
char *dgettext(const char *domainname, const char *msgid);
char *dcgettext(const char *domainname, const char *msgid, int category);
Аргументы, используемые в этих функциях, следующие:
const char *msgid
Переводимая строка. Она действует в качестве ключа к базе данных переводов.
const char *domainname
Текстовый домен, из которого нужно получить перевод. Таким образом, хотя main() вызвала textdomain() для установки собственного домена приложения, сообщения могут быть получены из других текстовых доменов. (Это наиболее применимо к сообщениям, которые могли бы быть, например, в текстовом домене библиотеки от третьей стороны.)
int category
Одна из описанных ранее категорий доменов (LC_TIME и т.п.). Доменом по умолчанию является то, что было раньше установлено с помощью textdomain() («messages», если textdomain() никогда не вызывалась). Категорией по умолчанию является LC_MESSAGES. Предположим, main() делает следующий вызов:
textdomain("killerapp");
Тогда 'gettext("my message")' эквивалентно 'dgettext("killerapp", "my message")'. Обе функции, в свою очередь, эквивалентны 'dcgettext("killerapp", "my message", LC_MESSAGES)'.
В 99,9% времени бывает нужно использовать gettext(). Однако, другие функции обеспечивают гибкость при работе с другими текстовыми доменами или категориями локалей. Скорее всего, эта гибкость потребуется при программировании библиотек, поскольку автономная библиотека почти наверняка будет использовать свой собственный текстовый домен.
Все функции возвращают строки. Строка является либо переводом данного msgid, либо, если перевода не существует, первоначальной строкой. Таким образом, всегда имеется какой-нибудь вывод, даже если это первоначальное сообщение (предположительно на английском). Например:
/* Каноническая первая программа, локализованная версия. */
#include <stdio.h>
#include <locale.h>
#include <libintl.h>
int main(void) {
setlocale(LC_ALL, "");
printf("%sn", gettext("hello, world"));
return 0;
}
Хотя сообщение является простой строкой, мы не используем ее непосредственно в форматирующей строке printf(), поскольку в общем перевод может содержать символы %.
Вскоре, в разделе 13.3.4 «Упрощение использования gettext()», мы увидим, как облегчить использование gettext() в крупномасштабных, реальных программах.
13.3.3. Работа с множественными числами: ngettext()
Перевод во множественном числе доставляет дополнительные трудности. Простой код мог бы выглядеть примерно так:
printf("%d word%s misspelledn", nwords, nwords > 1 ? "s" : "");
/* или */
printf("%d %s misspelledn", nwords, nwords == 1 ? "word" : "words").
Это подходит для английского языка, но перевод становится трудным. Во-первых, во многих языках множественное число не образуется с такой же легкостью, как в английском (добавлением суффикса s для большинства слов). Во-вторых, во многих языках, особенно в Восточной Европе, имеются несколько форм множественного числа, каждая из которых указывает на то, сколько объектов обозначает форма. Соответственно даже код наподобие следующего не будет достаточным:

