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() / _() 获取翻译文本

posted @ 2025-10-21 15:17  江海余生  阅读(17)  评论(0)    收藏  举报