Pine Blog

c/c++ ,gettext,软件的多语言支持(i18n)

1、采用 GNU gettext提供多语言支持

  • 原理就是: 当你在输出的字符串前加上 gettext
    函数时,系统会去对应的文件(.mo文件)中找该字符串是否存在翻译,如果存在就显示翻译后的字符串,如果没有对应翻译项就直接显示。

一个小例程,用于演示:

cat >hello.cpp <<EOF
// hello.cpp
#include <libintl.h>
#include <locale.h>
#include <iostream>
int main (){
    setlocale(LC_ALL, "");
    bindtextdomain("hello", ".");
    textdomain( "hello");  // 这里设置.mo的文件名字为: hello.mo
    std::cout << gettext("hello, world!") << std::endl;  // 输出的字符串,用于被替换的
}
EOF

编译上述文件:

g++ -o hello hello.cpp
  • 找出源代码中所有需要转换的字符串,并生成 .pot 文件。(Extracted text from C++ source file (portable object template))
    // -d, --default-domain=名称 使用<名称.po>输出(而不是 messages.po)

// -o, --output=文件 将输出写入指定文件
// -kWORD, --keyword=WORD 查找 WORD 作为一个额外的关键字(如果字符串用额外的关键字标出了,例如: ("Hello world!n"),则关键字为
// 如果关键字不是 gettext 则需要显式加上 -k 选项

xgettext --package-name hello --package-version 1.2 --default-domain hello --output hello.pot hello.cpp

// 可以简化为:

xgettext -kXXX -o hello.pot XXX.cpp
  • 将 .pot 文件转换成 .po 文件,并编辑。注:可以不通过源文件生成的.po文件直接自己一条一条添加,这个.po文件可以跨系统,用于生成.mo文件。(Modified text for Chinese with translations added)

    // --no-translator 表示:假定 PO 文件是自动生成的,不然会让你输入电子邮件地址,以反馈翻译问题
    msginit --no-translator --locale zh_CN.UTF-8 --output-file hello_chinese.po --input hello.pot
    简化版:msginit -l zh_CN.UTF-8 -i hello.pot -o hello.po

    // 编辑 hello_chinese.po 文件,并添加替换中文翻译字符串
    #: hello.cpp:9
    msgid "hello, world!"
    msgstr "你好,世界!"

    • 将 .po 文件转化为 .mo 文件,该文件即为我们最后需要使用的文件。(Binary translated text for Chinese used at run-time)

    mkdir -p zh_CN.UTF-8/LC_MESSAGES
    msgfmt --check --verbose --output-file ./zh_CN.UTF-8/LC_MESSAGES/hello.mo hello_chinese.po

    • 设置环境变量,运行程序即可:

    export LANG=zh_CN.UTF-8 # locale 查看系统变量
    export LANGUAGE=zh_CN.UTF-8 # 该环境变量决定了你去哪个文件夹中找 .mo 文件
    ./hello

2、关于格式化字符串(即在 .po 文件中匹配数字等):

  • C/gettext:

    snprintf(msg,sizeof(msg),gettext("This is the message to %1$s about %2$s"),who,what);

  • C++ using boost.locale:

    using boost::format;
    std::ostringstream ss;
    ss << format(gettext("This is the message to %1% about %2%")) % who % what;

  • C++ using boost.locale:

    using boost::locale::format;
    using boost::locale::translate;
    std::ostringstream ss;
    ss << format(translate("This is the message to {1} about {2}")) % who % what;

未经允许不得转载:Pine Blog » c/c++ ,gettext,软件的多语言支持(i18n)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

Pine Blog
Anywhere, Anytime
E-mail:59054872@qq.com
苏ICP备15059480号-1