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

原理就是: 当你在输出的字符串前加上 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

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

C/gettext:

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

C++/gettext:

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;

在使用 linux 系统时,可以直接将中文赋值给 std::string 0.0 :-0 …amazing 自动转成了 utf-8 格式

http://stackoverflow.com/questions/402283/stdwstring-vs-stdstring

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值