使用 gettext 实现多语言支持
gettext 是一个用于国际化(i18n)和本地化(l10n)的工具,主要用于管理软件中的文本翻译。
-
项目结构:
myapp ├── src │ └── main.c ├── po │ ├── myapp.pot # 翻译模板 │ ├── en_US.po # 翻译文件 │ ├── zh_CN.po # 翻译文件 │ └── LINGUAS # 支持语言文件 └── locale # 存储翻译产物 ├── en_US │ └── LC_MESSAGES │ └── myapp.mo └── zh_CN └── LC_MESSAGES └── myapp.mo -
标记可翻译字符串:
在源代码中,使用
gettext函数标记需要翻译的字符串:src/main.c:#include <libintl.h> #include <locale.h> #include <stdio.h> int main() { setlocale(LC_ALL, ""); // 设置语言环境(使用环境变量) bindtextdomain("myapp", "./locale"); // 绑定消息域 textdomain("myapp"); // 设置消息域 printf(gettext("Hello, World!")); }在实际使用时不要包含非 ASCII 注释
或者,使用缩写形式
_(通常需要定义宏):printf(_("Hello, World!")); -
提取翻译字符串:
使用
xgettext工具从源码中提取标记的字符串,生成.pot(Portable Object Template)文件。这个文件包含了所有需要翻译的原始字符串。xgettext -o po/myapp.pot src/main.c.pot是翻译的模板文件。接下来我们要用它来生成翻译目标文件。 -
创建翻译文件:
为每种目标语言创建一个
.po文件:msginit -i po/myapp.pot -o po/zh_CN.po -l zh_CN.UTF-8 --no-translator -
翻译字符串:
使用文本编辑器或专用的翻译工具(如 Poedit)打开
.po文件,填写每个原始字符串的翻译。# Chinese translations for PACKAGE package. # Copyright (C) 2025 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Automatically generated, 2025. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-05-16 23:50+0800\n" "PO-Revision-Date: 2025-05-16 23:50+0800\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: zh\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ASCII\n" "Content-Transfer-Encoding: 8bit\n" #: main.c:9 #, c-format msgid "Hello, World!" msgstr "你好,世界!" -
编译翻译文件:
使用
msgfmt将.po文件编译为机器可读的.mo文件。msgfmt -o locale/zh_CN/LC_MESSAGES/myapp.mo po/zh_CN.po -
编译程序:
gcc -o myapp -I/opt/gettext/include -L/opt/gettext/lib -lintl src/main.c -
运行:
$ LC_MESSAGES="en_US.UTF-8" ./myapp Hello, World! $ LC_MESSAGES="zh_CN.UTF-8" ./myapp 你好,世界!

浙公网安备 33010602011771号