printf还有其他选择吗?

时间:2010-10-12 09:01:35

标签: c++ c linux translation printf

我必须创建一个必须在几个* 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()不是一个选项。

4 个答案:

答案 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}

现在你可能会说一个更聪明的格式字符串会解决这个问题,但有几个原因会导致错误:

  • 这是一个非常简单的例子,可能会有其他更复杂的东西(我试着得到一些例子,但是我们的翻译人员已经明确表示他们有更紧迫的工作,而不是将自己提交给我的每一个心血来潮)。 / LI>
  • 格式字符串的重点是外部化翻译。如果格式字符串本身特定于翻译目标,则通过外部化文本获得的收益很少。
  • 开发人员不应该关注像{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)

你想要大多数Unix系统常用的%n $ s扩展名。

"Hi %1$s, you are %2$s."

请参阅底部的printf

中的德语示例

此致 DaveF