我必须创建一个必须在几个* nix平台(Linux,AIX,...)上运行的软件。
我需要处理国际化,我的翻译字符串采用以下形式:
"Hi %1, you are %2." // English
"Vous êtes %2, bonjour %1 !" // French
此处%1
代表名称,%2
代表另一个字词。我可以改变格式,这不是问题。
我尝试使用printf()
,但您无法指定参数的顺序,只需指定其类型即可。
"Hi %s, you are %s"
"Vous êtes %s, bonjour %s !"
现在无法知道用于替换%s
的参数:printf()
只使用第一个,然后是下一个。
printf()
有替代方法吗?
注意:gettext()
不是一个选项。
答案 0 :(得分:25)
POSIX printf()
支持位置参数。
printf("Hi %1$s, you are %2$s.", name, status);
printf("Vous êtes %2$s, bonjour %1$s !", name, status);
答案 1 :(得分:25)
我并不是要成为坏消息的承载者,但你提出的建议实际上是一个坏主意。我为一家非常认真对待i18n的公司工作,我们已经(痛苦地)发现你不能把单词插入这样的句子中,因为它们通常没有任何意义。
我们所做的只是简单地将错误文本与变量位断开,以避免这些问题。例如,我们将生成错误:
XYZ-E-1002 Frobozz not configured for multiple zorkmids (F22, 7).
然后,在错误描述中,您只是说明末尾括号中的两个值是Frobozz标识符和您尝试对其造成的zorkmids数。
这使得i18n翻译成为一项非常简单的任务,因为在翻译时,您需要所有所需的语言元素,而不必担心变量位应该是单数还是复数,男性还是女性,第一,第二或第三个变化(无论实际意味着什么)。
翻译团队只需要转换"Frobozz not configured for multiple zorkmids"
,这样就容易多了。
对于那些想要看一个具体例子的人,我从翻译中找到了一些东西(改变了足够的东西来保护有罪的人)。
在某些时候,有人提交了以下内容:
The {name} {object} is invalid
其中{name}
是对象的名称(客户,订单等),{object}
是对象类型本身(表,文件,文档,存储过程等)。
简单到英语,开发人员的主要(可能是唯一的)语言,但在翻译成德语/瑞士德语时遇到了问题。
虽然“客户文档”正确地(在位置意义上)转换为Kundendokument
,但格式字符串在两个单词之间有空格的事实是一个问题。这基本上是因为开发人员试图让句子听起来更自然,但不幸的是,基于他们有限的经验,这只是更自然。
更大的问题是“客户存储过程”变成gespeichertes Verfahren der Kunden
,字面意思是“客户的存储过程”。虽然德国客户可能在Kunden dokument
中留出了空格,但无法成功将gespeichertes Verfahren der Kunden
强加到{name} {object}
。
现在你可能会说一个更聪明的格式字符串会解决这个问题,但有几个原因会导致错误:
{possible-pre-adjectives} {possible-pre-owner} {object} {possible-post-adjectives} {possible-post-owner} {possible-postowner-adjectives}
这样的格式字符串。这是翻译团队的工作,因为他们了解细微差别。请注意,引入断开连接很好地回避了这个问题:
The object specified by <parameter 1>, of type <parameter 2>, is invalid. Parameter 1 = {name}. Parameter 2 = {object}. Der sache nannte <parameter 1>, dessen art <parameter 2> ist, ist falsch. Parameter 1 = {name}. Parameter 2 = {object}.
最后一个翻译是我的翻译之一,请不要用它来质疑我们翻译的质量。毫无疑问,更流利的德语演讲者会从中获得好笑。
答案 2 :(得分:11)
boost.format支持这种方式,就像在python中一样,但这适用于C ++
答案 3 :(得分:9)