【发布时间】:2016-10-28 09:51:22
【问题描述】:
我试图弄清楚为什么 GNU gettext 在本地化方面的行为与 strftime 或 printf 不同。我从头到尾阅读了整个手册,但示例相当简单。我已将问题简化为一个简单的 C 程序。
任务是通过用户输入在应用程序中切换区域设置以接收本地化文件输出。
我的地区:
LANG=de_DE.UTF-8
LC_CTYPE="de_DE.UTF-8"
LC_COLLATE="de_DE.UTF-8"
LC_TIME="de_DE.UTF-8"
LC_NUMERIC="de_DE.UTF-8"
LC_MONETARY="de_DE.UTF-8"
LC_MESSAGES="de_DE.UTF-8"
LC_ALL=
考虑这个 C 示例:
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <time.h>
#include <math.h>
#include "my-i18n.h"
#define PI acos(-1.0)
static char *locales[] = {
"de_DE.UTF-8",
"ru_RU.UTF-8",
"he_IL.UTF-8",
"es_ES.UTF-8",
"C",
};
void localize(char *locale, struct tm *time) {
printf("==============================================================\n");
printf("Passed locale: %s\n", locale);
char *setlocale_out = setlocale(LC_ALL, locale);
printf("Set locale: %s\n", setlocale_out);
char buffer[80];
strftime(buffer, sizeof(buffer), "%c", time);
printf("Localized time: %s\n", buffer);
printf("Get rational, π: %f\n", PI);
printf(_("Hello World!\n"));
printf(_("Goodbye!\n"));
}
int main(void) {
time_t rawtime = time(NULL);
struct tm *time;
localtime(&rawtime);
time = localtime(&rawtime);
bindtextdomain("my-i18n", LOCALEDIR);
textdomain("my-i18n");
int i;
for (i = 0; i < sizeof(locales)/sizeof(locales[0]); i++) {
localize(locales[i], time);
}
return EXIT_SUCCESS;
}
及其输出:
==============================================================
Passed locale: de_DE.UTF-8
Set locale: de_DE.UTF-8
Localized time: Fr 28 Okt 11:44:24 2016
Get rational, π: 3,141593
Setting LANG=de_DE.UTF-8
Hallo Welt!
Tschüß!
==============================================================
Passed locale: ru_RU.UTF-8
Set locale: ru_RU.UTF-8
Localized time: пятница, 28 октября 2016 г. 11:44:24
Get rational, π: 3,141593
Setting LANG=ru_RU.UTF-8
Hallo Welt!
Tschüß!
==============================================================
Passed locale: he_IL.UTF-8
Set locale: he_IL.UTF-8
Localized time: CEST 11:44:24 2016 אוק 28 ו'
Get rational, π: 3.141593
Setting LANG=he_IL.UTF-8
Hallo Welt!
Tschüß!
==============================================================
Passed locale: es_ES.UTF-8
Set locale: es_ES.UTF-8
Localized time: vie 28 oct 11:44:24 2016
Get rational, π: 3,141593
Setting LANG=es_ES.UTF-8
Hallo Welt!
Tschüß!
==============================================================
Passed locale: C
Set locale: C
Localized time: Fri Oct 28 11:44:24 2016
Get rational, π: 3.141593
Setting LANG=C
Hallo Welt!
Tschüß!
如您所见,strftime 和 printf 完全符合我的预期,但 gettext 只考虑了我的外部语言环境。在 Google 和 SO 搜索之后,我发现bindtextdomain 和/或textdomain 必须在每个setlocale 之后执行。此外,我必须执行 putenv("LANG=...") 才能强制 gettext 工作。
修改后的C代码:
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <time.h>
#include <math.h>
#include "my-i18n.h"
#define PI acos(-1.0)
static char *locales[] = {
"de_DE.UTF-8",
"ru_RU.UTF-8",
"he_IL.UTF-8",
"es_ES.UTF-8",
"C",
};
void localize(char *locale, struct tm *time) {
printf("==============================================================\n");
printf("Passed locale: %s\n", locale);
char *setlocale_out = setlocale(LC_ALL, locale);
printf("Set locale: %s\n", setlocale_out);
char buffer[80];
strftime(buffer, sizeof(buffer), "%c", time);
printf("Localized time: %s\n", buffer);
printf("Get rational, π: %f\n", PI);
printf("Setting LANG=%s\n", locale);
setenv("LANG", locale, 1);
bindtextdomain("my-i18n", LOCALEDIR);
textdomain("my-i18n");
printf(_("Hello World!\n"));
printf(_("Goodbye!\n"));
}
int main(void) {
time_t rawtime = time(NULL);
struct tm *time;
localtime(&rawtime);
time = localtime(&rawtime);
int i;
for (i = 0; i < sizeof(locales)/sizeof(locales[0]); i++) {
localize(locales[i], time);
}
return EXIT_SUCCESS;
}
和输出:
==============================================================
Passed locale: de_DE.UTF-8
Set locale: de_DE.UTF-8
Localized time: Fr 28 Okt 11:50:33 2016
Get rational, π: 3,141593
Setting LANG=de_DE.UTF-8
Hallo Welt!
Tschüß!
==============================================================
Passed locale: ru_RU.UTF-8
Set locale: ru_RU.UTF-8
Localized time: пятница, 28 октября 2016 г. 11:50:33
Get rational, π: 3,141593
Setting LANG=ru_RU.UTF-8
Привет мир!
Пока!
==============================================================
Passed locale: he_IL.UTF-8
Set locale: he_IL.UTF-8
Localized time: CEST 11:50:33 2016 אוק 28 ו'
Get rational, π: 3.141593
Setting LANG=he_IL.UTF-8
Hello World!
Goodbye!
==============================================================
Passed locale: es_ES.UTF-8
Set locale: es_ES.UTF-8
Localized time: vie 28 oct 11:50:33 2016
Get rational, π: 3,141593
Setting LANG=es_ES.UTF-8
¡Hola mundo!
¡Adios!
==============================================================
Passed locale: C
Set locale: C
Localized time: Fri Oct 28 11:50:33 2016
Get rational, π: 3.141593
Setting LANG=C
Hello World!
Goodbye!
有人能解释一下这种“奇怪”的行为吗?
编辑:我在邮件列表中提出了它:http://lists.gnu.org/archive/html/bug-gettext/2016-11/msg00002.html
【问题讨论】:
标签: c localization gettext