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()
不是一个选项。
I have to create a software that must work on several *nix platforms (Linux, AIX, ...).
I need to handle internationalization and my translation strings are in the following form:
"Hi %1, you are %2." // English
"Vous êtes %2, bonjour %1 !" // French
Here %1
stand for the name, and %2
for another word. I may change the format, that's not an issue.
I tried to use printf()
but you cannot specify the order of the parameters, you just specify their types.
"Hi %s, you are %s"
"Vous êtes %s, bonjour %s !"
Now there is no way to know which parameter to use for replacement of %s
: printf()
just uses the first one, then the next.
Is there any alternative to printf()
that deals with this ?
Note: gettext()
is not an option.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我并不是想传达坏消息,但你的提议实际上是一个坏主意。我在一家非常重视国际化的公司工作,我们(痛苦地)发现你不能只是将单词插入这样的句子中,因为它们通常毫无意义。
我们所做的就是简单地将错误文本与变量位完全断开,以避免这些问题。例如,我们将生成一个错误:
然后,在错误描述中,您只需说明末尾括号中的两个值是 Frobozz 标识符和您尝试对其施加的 zorkmids 数量。
这使得国际化翻译成为一项极其简单的任务,因为在翻译时您已经拥有了所需的所有语言元素,而不必担心变量位应该是单数还是复数、男性还是女性、第一还是第二,或第三种变格(无论其实际含义是什么)。
翻译团队只需转换
“Frobozz notconfiguration for multiple zorkmids”
,这就容易多了。对于那些想查看具体示例的人,我从我们的翻译机构那里得到了一些反馈(已更改了足够的内容以保护有罪者)。
在某个时候,有人提交了以下内容:
其中
{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-所有者} {possible-postowner-adjectives}
。这是翻译团队的工作,因为他们了解其中的细微差别。请注意,引入断开连接很好地回避了这个问题:
最后的翻译是我的翻译之一,请不要用它来质疑我们翻译人员的质量。毫无疑问,德语说得更流利的人会从中大笑。
I don't mean to be the bearer of bad tidings but what you're proposing is actually a bad idea. I work for a company that take i18n very seriously and we've discovered (painfully) that you cannot just slot words into sentences like that, since they often make no sense.
What we do is to simply disconnect the error text from the variable bits altogether, so as to avoid these problems. For, example, we'll generate an error:
And then, in the description of the error, you state simply that the two values in the parentheses at the end were the Frobozz identifier and the number of zorkmids you tried to inflict on it.
This leaves i18n translation as an incredibly easy task since you have, at translation time, all of the language elements you need without worrying whether the variable bits should be singular or plural, masculine or feminine, first, second, or third declension (whatever the heck that actually means).
The translation team simply has to convert
"Frobozz not configured for multiple zorkmids"
and that's a lot easier.For those who would like to see a concrete example, I have something back from our translation bods (with enough stuff changed to protect the guilty).
At some point, someone submitted the following:
where
{name}
was the name of a object (customers, orders, etc) and{object}
was the object type itself (table, file, document, stored procedure, etc).Simple enough for English, the primary (probably only) language of the developers, but they struck a problem when translating to German/Swiss-German.
While the "customers document" translated correctly (in a positional sense) to
Kundendokument
, the fact that the format string had a space between the two words was an issue. That was basically because the developers were trying to get the sentence to sound more natural but, unfortunately, only more natural based on their limited experience.A bigger problem was with the "customers stored procedure" which became
gespeichertes Verfahren der Kunden
, literally "stored procedure of the customers". While the German customers may have put up with a space inKunden dokument
, there is no way to imposegespeichertes Verfahren der Kunden
onto{name} {object}
successfully.Now you may say that a cleverer format string would have fixed this but there are several reasons why that would be incorrect:
{possible-pre-adjectives} {possible-pre-owner} {object} {possible-post-adjectives} {possible-post-owner} {possible-postowner-adjectives}
. That is the job of the translation teams since they understand the nuances.Note that introducing the disconnect sidesteps this issue nicely:
That last translation was one of mine, please don't use it to impugn the quality of our translators. No doubt more fluent German speakers will get a good laugh out of it.
POSIX
printf()
支持位置参数。POSIX
printf()
supports positional arguments.boost.format 像 python 一样支持这种方式,但是这是针对 C++ 的
boost.format supports this the way like in python however this is for C++
您需要大多数 Unix 系统通用的 %n$s 扩展名。
请参阅底部的德语示例 printf
问候
戴夫·F
You want the %n$s extension that is common to most Unix systems.
See the German example at the bottom printf
Regards
DaveF