Книга: Linux программирование в примерах

13.3.3. Работа с множественными числами: ngettext()

13.3.3. Работа с множественными числами: ngettext()

Перевод во множественном числе доставляет дополнительные трудности. Простой код мог бы выглядеть примерно так:

printf("%d word%s misspelledn", nwords, nwords > 1 ? "s" : "");
/* или */
printf("%d %s misspelledn", nwords, nwords == 1 ? "word" : "words").

Это подходит для английского языка, но перевод становится трудным. Во-первых, во многих языках множественное число не образуется с такой же легкостью, как в английском (добавлением суффикса s для большинства слов). Во-вторых, во многих языках, особенно в Восточной Европе, имеются несколько форм множественного числа, каждая из которых указывает на то, сколько объектов обозначает форма. Соответственно даже код наподобие следующего не будет достаточным:

if (nwords == l)
 printf("one word misspelledn");
else
 printf("%d words misspelledn", nwords);

Решением является параллельный набор процедур специально для форматирования множественных значений:

#include <libintl.h> /* GLIBC */
char *ngettext(const char *msgid, const char *msgid_plural,
 unsigned long int n);
char *dngettext(const char *domainname, const char *msgid,
 const char *msgid_plural, unsigned long int n);
char *dcngettext(const char *domainname, const char *nmgid,
 const char *msgid_plural, unsigned long int n,
 int category)

Помимо первоначального аргумента msgid, эти функции принимают дополнительные аргументы:

const char *msgid_plural

Строка по умолчанию для использования в качестве множественного числа. Вскоре будут примеры.

unsigned long int n

Число имеющихся элементов.

Список сообщений каждой локали указывает, как переводить множественные числа.[145] Функция ngettext() (и ее варианты) проверяет n и на основании спецификации в списке сообщений возвращает соответствующий перевод msgid. Если в списке нет перевода для msgid, или находясь в локали «С», ngettext() возвращает msgid, если 'n == 1'; в противном случае она возвращает msgid_plural. Таким образом, наш пример ошибочных слов выглядит следующим образом:

printf("%sn", ngettext("%d word misspelled", "%d words misspelled", nwords), nwords);

Обратите внимание, что nwords должен быть передан ngettext() для выбора форматирующей строки, а затем printf() для форматирования. Вдобавок, будьте осмотрительны и не используйте макрос или выражение, значение которого каждый раз изменяется, как в случае 'n++'! Такое может случиться, если вы осуществляете глобальное редактирование, добавляя вызовы ngettext() и не обращая на это внимания.

Оглавление книги


Генерация: 1.548. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз