void copyright(void) {
printf("%s\n", gettext(copyrights));
}
Обратите внимание, что мы сделали два изменения. Во-первых, copyrights
теперь является одной длинной строкой, созданной с использованием возможности конкатенации строк стандартного C. Эта простая строка затем включена в вызов gettext_noop()
. Нам нужна одна строка, чтобы легальности могли быть переведены в виде одного элемента
Второе изменение заключается в непосредственном выводе перевода в виде одной строки в copyright()
.
К этому времени вы, возможно, думаете: «Вот здорово, набирать каждый раз 'gettext(...)
' довольно неприятно». Ну, вы правы. Это не только создает лишнюю работу по набиванию, но также и затрудняет чтение исходного кода. Соответственно, когда вы используете заголовочный файл gettext.h
, руководство GNU gettext
рекомендует включить два других макроса с именами _()
и N_()
следующим образом:
#define ENABLE_NLS 1
#include "gettext.h"
#define _(msgid) gettext(msgid)
#define N_(msgid) msgid
Такой подход снижает накладные расходы по использованию gettext()
всего лишь тремя дополнительными символами для переводимой строковой константы и всего лишь четырьмя символами для статических строк:
#include
#define ENABLE_NLS 1
#include "gettext.h"
#define _(msgid) gettext(msgid)
#define N_(msgid) msgid
...
static char copyrights[] =
N_("Copyright 2004, Jane Programmer\n"
"Permission is granted ...\n"
/* ... Здесь куча легальностей */
"So there.");
void copyright(void) {
printf("%s\n", gettext(copyrights));
}
int main(void) {
setlocale(LC_ALL, ""); /* gettext.h gets
printf("%s\n", _("hello, world"));
copyright();
exit(0);
}
Эти макросы скромны, и на практике все GNU программы, использующие GNU gettext
, следуют этому соглашению. Если вы собираетесь использовать GNU gettext
, вам тоже нужно следовать этому соглашению.
13.3.4.2. Только GLIBC:
Для программ, которые будут использоваться лишь на системах с GLIBC, использование заголовочных файлов и макросов похоже, но проще:
#include
#include
#define _(msgid) gettext(msgid)
#define N_(msgid) msgid
/* ... все остальное то же ... */
Как мы видели ранее, заголовочный файл
объявляет gettext()
и другие функции. Вам все равно нужно определять _()
и N_()
, но не нужно беспокоиться о ENABLE_NLS
или включении с исходным кодом вашей программы файла gettext.h
.
13.3.5. Перестановка порядка слов с помощью printf()
Иногда при переводах порядок слов, естественный для английского языка, не подходит в других языках. Например, на английском прилагательные идут перед определяемыми существительными, а на многих других языках — после. Таким образом, следующий код представляет проблему:
char *animal_color, *animal;
if (...) {
animal_color = _("brown");
animal = _("cat");
} else if (...) {
...
} else {
...
}
printf(_("the %s %s looks at you enquiringly.\n"), animal_color, color);
Здесь форматирующая строка, animal_color
и animal
неудачно включены в вызов gettext()
. Однако, после перевода утверждение будет неверным, поскольку
Чтобы обойти это, версия семейства printf()
POSIX (но $
, %
. Например printf("%2$s, %1s\n", "world", "hello")
;
Указатель положения обозначает аргумент из списка, который следует использовать, отсчет начинается с 1 и не включает саму форматирующую строку. Этот пример выводит знаменитое сообщение 'hello, world
' в правильном порядке.
GLIBC и Solaris реализуют эту возможность. Поскольку это часть POSIX, если printf()
вашего поставщика Unix не реализует ее, она вскоре должна появиться.