const char *dirname);Полезные каталоги включают '
./tmpchar *td_dir;setlocale(LC_ALL, "");textdomain("killerapp");if ((td_dir = getenv("KILLERAPP_TD_DIR")) != NULL) bindtextdomain("killerapp", td_dir);bindtextdomain()gettext()13.3.7. Подготовка интернационализированных программ
К настоящему моменту мы рассмотрели все компоненты, из которых состоит интернационализированная программа. Данный раздел подводит итоги.
1. Включите в свое приложение заголовочный файл
gettext.h_()N_()ENABLE_NLS2. Вызовите соответствующим образом
setlocale()setlocale(LC_ALL, "")3. Выберите для приложения текстовый домен и установите его с помощью
textdomain()4. При тестировании свяжите текстовый домен с определенным каталогом при помощи
bindtextdomain()5. Используйте соответствующим образом
strfmon()strftime()'nl_langinfo()strftime()6. Пометьте все строки, которые должны быть переведены, соответствующими вызовами
_()N_()Хотя некоторые не следует так помечать. Например, если вы используете
getopt_long()%d %d\n7. В нужных местах используйте
ngettext()8. Упростите жизнь для своих переводчиков, используя строки с полными предложениями вместо замены слов с помощью
%s?:if (/* <i>возникла ошибка</i> */) { /* ВЕРНО */ /* Использовать несколько строк для упрощения перевода. */ if (input_type == INPUT_FILE) fprintf(stderr, _("%s: cannot read file: %s\n"), argv[0], strerror(errno)); else fprintf(stderr, _("%s: cannot read pipe: %s\n"), argv[0], strerror(errno));Это лучше, чем
if (/* <i>возникла ошибка</i> */) { /* НЕВЕРНО */ fprintf(stderr, _("%s: cannot read %s: %s\n"), argv[0], input_type == INPUT_FILE ? _("file") : _("pipe"), strerror(errno));}Как только что показано, хорошей мыслью является включение комментария, сообщающего о намеренном использовании нескольких строк, чтобы упростить перевод сообщений.
13.3.8. Создание переводов
После интернационализации программы необходимо подготовить переводы. Это осуществляется с помощью нескольких инструментов уровня оболочки. Мы начнем с интернационализированной версии
ch06-echodate.ctime_t/* ch13-echodate.c --- демонстрация переводов */#include <stdio.h>#include <time.h>#include <locale.h>#define ENABLE_NLS 1#include "gettext.h"#define _(msgid) gettext(msgid)#define N_(msgid) msgidint main (void) { struct tm tm; time_t then; setlocale(LC_ALL, ""); bindtextdomain("echodate", "."); textdomain("echodate"); printf("%s", _("Enter a Date/time as YYYY/MM/DD HH:MM:SS : ")); scanf("%d/%d/%d %d:%d:%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec); /* Проверка ошибок для краткости опущена. */ tm.tm_year -= 1900; tm.tm_mon -= 1; tm.tm_isdst = -1; /* О летнем времени ничего не известно */ then = mktime(&tm); printf(_("Got: %s"), ctime(&then)); exit(0);}Мы намеренно использовали
"gettext.h"<gettext.h>gettext"gettext.h"gettext