以C ++为基础的本地化文本最佳实践
在当前的C ++标准(C ++ 03)中,关于文本本地化的规范太少,并且使得C ++开发人员在使用本地化文本(肯定C ++ 0x标准将在稍后提供帮助)时比平常更加困难。
假设以下场景(来自真正的PC-Mac游戏开发案例):
在这类应用程序中,用C ++管理本地化文本的最佳实践是什么?
去年我研究了这一点,我唯一能确定的是你应该使用std::wstring
或std::basic_string<ABigEnoughType>
来操作应用程序中的文本。 我停止了我的研究,因为我正在更多地研究“文本显示”问题(在实时3D的情况下),但我想有一些最佳实践来管理原始C ++中的本地化文本,而不仅仅是“使用Unicode” 。
所以,欢迎所有的最佳实践,建议和信息(跨平台让我觉得很难)!
在一家小型电子游戏公司Black Lantern Studios,我曾担任Lionel Trains DS游戏的首席开发人员。 我们本地化为英文,西班牙文,法文和德文。 我们事先知道所有的语言,所以在编译时包括它们是唯一的选择。 (他们被烧成ROM,你看)
我可以告诉你我们所做的一些事情。 我们的字符串在启动时根据玩家的语言选择加载到数组中。 每个单独的语言进入一个单独的文件,其中所有字符串的顺序相同。 字符串1始终是游戏的标题,字符串2总是第一个菜单选项,依此类推。 我们将enum
键入了enum
,因为integer
索引非常快,而在游戏中,速度就是一切。 (其他答案之一链接的解决方案使用string
查找,我倾向于避免这种查找。)显示字符串时,我们使用printf()
类型函数将标记替换为值。 “火车3正在离开城市1”。
现在为一些陷阱。
1)在语言之间,短语顺序完全不同。 “火车3正在离开城市1”。 翻译成德语,后面是“从城市1,3号火车正在离开”。 如果您使用的是printf()
而您的字符串是“Train%d正在离开城市%d”。 德国人最终会说“从城市3开始,列车1正在起飞。” 这是完全错误的。 我们通过强迫翻译保留相同的词序来解决这个问题,但我们最终得到了一些非常糟糕的德语。 如果我再次这样做,我会写一个函数,它将字符串和一个从零开始的数组放入其中。 然后我会使用像%0
和%1
这样的标记,基本上将数组索引嵌入到字符串中。 更新:@Jonathan Leffler指出,符合POSIX的printf()
支持使用%2$s
类型标记,其中2$
部分指示printf()
用第二个附加参数填充该标记。 只要速度足够快,这将非常方便。 自定义解决方案可能仍然更快,所以您需要确保并测试两者。
2)语言差异很大。 英语中有30个字符在德语中有时会出现多达110个字符。 这意味着它往往不适合我们正在使用的屏幕。 这对于PC / Mac游戏来说可能不是那么重要,但是如果你正在做的任何工作中文本必须放在一个定义好的框中,你就会想到这一点。 为了解决这个问题,我们尽可能多地从我们的文本中剥离了其他语言的形容词。 这缩短了句子,但保留了意思,如果失去了一点味道。 后来我设计了一个可以使用的应用程序,它将包含字体和框的大小,并允许翻译人员进行自己的修改,以便将文本放入框中。 不知道他们是否实施过它。 如果你有这个问题,你也可以考虑滚动文本区域。
3)就跨平台而言,我们为本地化系统编写了非常纯粹的C ++。 我们编写了自定义编码的二进制文件加载,以及一个自定义的程序,从语言文本的CSV转换为.h
与枚举和文件到语言地图,并为每种语言.lang
。 我们使用的平台最具体的东西是字体和printf()
函数,但是您将拥有适合您开发的任何地方的东西,或者可以根据需要编写自己的东西。
GNU Gettext完成了这一切。
我强烈不同意接受的答案。 首先,关于使用静态数组查找来加速文本查找的部分仅仅表明进行优化的人是非常缺乏经验的 - 计算所述文本的布局并渲染所述文本比使用哈希查找多使用2-4个数量级的时间。 如果有人想实现他们自己的语言库,它不应该基于静态数组。
但这并不是真正相关的,因为编写自己的语言库在你自己的游戏中使用甚至比毫无意义的过早优化更糟糕。 有一些非常好的理由永远不要编写自己的本地化库:
在规划编写本地化库的时间时,规划使用本地化库的时间要容易得多。 本地化图书馆存在,他们工作,许多人使用它们。
本地化是棘手的,所以你会弄错事情。 每种语言都会添加一个新的怪癖,这意味着无论何时将新语言添加到您自己的本地化本地化库中,您都需要再次更改代码以解释怪癖。 你知道有些语言有两种以上的复数形式,这取决于有问题的物品数量吗? 超过2性别(超过10,甚至)? 而且,在许多语言中,数字和日期格式在不同语言之间差异很大。
当您的应用程序成功时,您将需要添加对更多语言的支持。 您团队中没有人会说流利的语言。 如果他们已经知道他们正在使用的工具,雇用某人撰写翻译将会相当便宜 。
一个非常知名且完整的本地化库是GNU Gettext,它使用GPL,因此应避免商业性工作。 您可以使用boost库,它可以与Gettext文件一起使用,并且可以免费使用和修改任何类型的商业和非商业项目。
链接地址: http://www.djcxy.com/p/39573.html