字符串的多国语言支持解决方案 通用解决方案篇

时间:2022-12-27 03:02:13

write by 九天雁翎(JTianLing) -- blog.jtianling.com

新浪微博 -- 讨论新闻组 -- 代码库 -- 豆瓣

    在用Qt的时候,自然是使用Qt的解决方案,简单易用,参考《字符串的多国语言支持解决方案 Qt篇》。
    在不需要跨平台开发iPhone的应用时,自然使用iOS提供的多国语言支持解决方案
    但是,不能用Qt,也不是开发纯iOS应用的时候呢?那就只能自己想个办法解决这个问题了。

根据实际情况,该解决方案需要符合下面的条件:
1.代码中使用时,不应该有太多额外的负担,不降低代码的可读性
2.不用单独的工具也能使用

第一条很好解释,假如为了多国语言而浪费太多的精力实在不值得,所以这里放弃更加高效的int编码索引字符串的方式,那种方式的确更加高效,但是代码中需要使用宏/常量来索引字符串。
第二条就完全处于开发简单的考虑,不要神马分析,生成等乱七八糟的东西,所以也不会如很多解决方案一样使用啥excel,然后通过工具解析成二进制的格式,然后程序中去解析二进制数据,那不是自虐吗?
那么方案其实就慢慢出来了,以文本配置来存储多国语言的文字,一种语言一个文件。在文本配置的格式选择上,使用json。用字符串Key来索引字符串,索引失败时,就直接显示Key字符串。

首先,json的格式就是最简单的以key为索引的字符串组合,比如,我现在建立一个en.json表示英文,一个cn.json表示中文。
字符串的多国语言支持解决方案 通用解决方案篇

然后实现如下StringManager,该类为Singleton:(用jsoncpp为json的解析库)
头文件:
class StringManager : public Singleton<StringManager>
{
public:
  bool Init(const char* filename);

  std::string GetLocalizedString(const char* key);

private:
  Json::Value string_map_;
};

部分实现:

bool StringManager::Init( const char* filename ) {
  if ( !ReadJsonFromFile(filename, string_map_) ) {
    return false;
  }

  return true;
}

std::string StringManager::GetLocalizedString( const char* key ) {
  if (string_map_.isMember(key)) {
    return string_map_[key].asString();
  }
  else {
    return std::string(key);  // 当查找不到key时,直接显示key
  }
}

一般情况下,直接通过StringManager的GetLocalizedString函数来获取字符串即可,为了更加简单,定义如下的宏:
#define LS(key) StringManager::Instance()->GetLocalizedString(key)

使用时,先需要以字符串的配置文件名初始化StringManager,读取字符串信息。 以后,使用起来就和Qt中很类似了。即以LS()方式包含你需要显示的文字。
比如下面这样,为了减少其他无关信息,就没有添加显示部分的代码了:

在以上的例子中,我是使用utf8来保存多国语言,假如你是使用UTF16的话,请将相应的字符串表示改为宽字节即可。

小结:
因为没有额外的工具支持,这样的方式也许没有qt,iOS里面那么便捷,但是实现简单,容易理解,同时使用起来也足够的方便,最最重要的是,除了C++编译器,这套方案不依赖于平台或者其他神马东西,你随时随地都可以使用。(本例中用jsoncpp解析json,jsoncpp也仅依赖C++编译器存在)



原创文章作者保留版权 转载请注明原作者 并给出链接

write by 九天雁翎(JTianLing) -- blog.jtianling.com