C++ 多语言——GNU gettext
🌍 一、目标
我们希望程序能根据系统语言输出不同文本:
- 英文(默认) →
Hello, world! - 中文(简体) →
你好,世界!
📁 二、目录结构
myapp/
├── main.cpp
├── locale/
│ └── zh_CN/
│ └── LC_MESSAGES/
│ └── messages.po
💻 三、main.cpp 示例代码
#include <iostream>
#include <locale.h>
#include <libintl.h>
#define _(STRING) gettext(STRING)
int main() {
// 设置本地化环境
setlocale(LC_ALL, "");
// 指定语言文件目录和翻译域
bindtextdomain("messages", "./locale");
textdomain("messages");
// 测试输出
std::cout << _("Hello, world!") << std::endl;
std::cout << _("File not found") << std::endl;
return 0;
}
注意:
_()是gettext()的宏简写。"messages"是翻译域名(对应.mo文件名)。./locale是语言文件目录。
🧰 四、提取可翻译字符串
在终端运行:
xgettext -d messages -o messages.pot main.cpp
生成的 messages.pot 文件内容类似:
msgid "Hello, world!"
msgstr ""
msgid "File not found"
msgstr ""
🌐 五、创建中文翻译文件
msginit --locale=<语言代码> --input=<模板文件> --output=<输出文件>
msginit --locale=zh_CN.UTF-8 --input=message.pot --output=message.po
创建 locale/zh_CN/LC_MESSAGES/messages.po,内容如下:
msgid "Hello, world!"
msgstr "你好,世界!"
msgid "File not found"
msgstr "未找到文件"
修改main.cpp中的多语言文本之后,重新生成message.pot文件,更新message.po的命令:
msgmerge --update <原_po文件> <新_pot文件>
msgmerge --update locale/zh_CN/LC_MESSAGES/message.po message.pot
🧩 六、编译 .po 为 .mo
msgfmt -o locale/zh_CN/LC_MESSAGES/messages.mo locale/zh_CN/LC_MESSAGES/messages.po
⚙️ 七、编译 C++ 程序
在 Linux / macOS:
g++ main.cpp -o myapp -lintl
🚀 八、运行程序
1️⃣ 英文环境(默认)
./myapp
输出:
Hello, world!
File not found
2️⃣ 中文环境
LANG=zh_CN.UTF-8 ./myapp
输出:
你好,世界!
未找到文件
📘 九、总结
| 步骤 | 工具/函数 | 作用 |
|---|---|---|
| 提取字符串 | xgettext |
从源码提取可翻译文本 |
| 翻译 | .po 文件 |
编写多语言翻译 |
| 编译翻译文件 | msgfmt |
生成 .mo 二进制翻译文件 |
| 加载语言 | bindtextdomain()、textdomain() |
绑定翻译目录与域 |
| 翻译函数 | gettext() / _() |
获取翻译文本 |

浙公网安备 33010602011771号