6

我有这种格式化的字符串,我有一个翻译工作。在Xcode中省略参数的高级本地化

ENGLISH

 
"Check out the %[email protected] %[email protected] in %[email protected]: %[email protected]" = "Check out the %[email protected] %[email protected] in %[email protected]: %[email protected]" 

德文译本

 
"Check out the %[email protected] %[email protected] in %[email protected]: %[email protected]" = "Hör Dir mal %[email protected] in %[email protected] an: %[email protected]"; 

这些传递给[NSString stringWithFormat:]电话:

////////////////////////////////////// 
// Share Over Twitter 
NSString *frmt = NSLocalizedString(@"Check out the %[email protected] %[email protected] in %[email protected]: %[email protected]", @"The default tweet for sharing sounds. Use %[email protected] for where the sound type (Sound, mix, playlist) will be, %[email protected] for where the audio name will be, %[email protected] for the app name, and %[email protected] for where the sound link will be."); 
NSString *urlString = [NSString stringWithFormat:@"sounds/%@", SoundSoundID(audio)]; 
NSString *url = ([audio audioType] == UAAudioTypeSound ? UrlFor(urlString) : APP_SHORTLINK); 
NSString *msg = [NSString stringWithFormat: 
       frmt, 
       [[Audio titleForAudioType:[audio audioType]] lowercaseString], 
       [NSString stringWithFormat:@"\"%@\"", AudioName(audio)], 
       APP_NAME, 
       url]; 
returnString = msg; 

随着期望的和实际的结果:

ENGLISH

 
desired: "Check out the sound "This Sound Name" in My App Name: link_to_sound" 
actual: "Check out the sound "This Sound Name" in My App Name: link_to_sound" 

GERMAN

 
desired: "Hör Dir mal "This Sound Name" in My App Name an: link_to_sound" 
actual: "Hör Dir mal sound in "This Sound Name" an: My App Name" 



,通过在-[NSString stringWithFormat:]使用编号变量技术问题 的问题是,我的假设下,我可以做像这样的ngs,其中%[email protected]变量被完全省略。如果您注意到,格式字符串的德语翻译根本不使用第一个参数(%[email protected]),但它仍然出现在输出字符串中(“声音”)。

我在做什么错?

回答

7

这不是一个错误。编号参数不是C标准的一部分,而是IEEE标准1003.1的一部分,其中说明了以下内容(我的重点):

格式可以包含编号参数转换规范(即“%n $”和“ * m $“)或无编号参数转换规范(即%和*),但不是两者都有。唯一的例外是%%可以与“%n $”表单混合使用。格式字符串中编号和无编号参数说明的混合结果未定义。 使用编号参数规范时,指定第N个参数要求在格式字符串中指定从第一个到第(N-1)个所有前导参数。
+0

看来我所做的错在于对编号变量的省略进行假设。 – coneybeare 2010-06-01 15:08:28

+0

有趣的是,这在Android/Java中可以正常工作;必须是他们的(无效的)实现 – Opus1217 2016-01-01 18:50:01

0

看起来像一个bug给我。我认为你应该提交一个错误

CFString的格式化引擎独立于fprintf's,因此可能会有一些差异。例如,

printf("a %3$s\n", "b", "c", "d"); // prints "a d" 
NSLog(@"a %3$s\n", "b", "c", "d"); // prints "a b" 

您需要提供所有先前符,因为争论的宽度并不需要固定,如

printf("%2$llx %1$llx\n", 1LL, 2LL); // prints "2 1" 
printf("%2$llx\n", 1LL, 2LL);  // prints "200000000" !! 
NSLog(@"%2$llx %1$llx\n", 1LL, 2LL); // prints "2 1" 
NSLog(@"%2$llx\n", 1LL, 2LL);  // prints "1" 

iPhone OS的printf跳过1个失踪符4个字节,和CFString的格式化程序跳过0字节。


的解决方案是:

  • 重新整理指数,例如

    "Check out the %[email protected] %[email protected] in %[email protected]: %[email protected]" 
    "Hör Dir mal %[email protected] in %[email protected] an: %[email protected]"; 
    

  • 使用格式

    [@"%1$10p%2$10p%3$10p%4$10p" stringByAppendingString:frmt] 
    

    迫使要使用的所有参数,然后斩出与-substringFromIndex:前40个字符,或

  • 转换所有ObjC将对象转换为C字符串(char*)并使用snprintf

  • 编写自己的格式引擎。
  • +0

    我曾希望避免这些变通办法并将文件发回给译员。 booooo – coneybeare 2010-05-31 16:35:23

    +0

    你能解释一下2号在做什么吗? – coneybeare 2010-05-31 23:14:35

    +0

    我试图实现第五个选项,在这里:http://stackoverflow.com/questions/2946649/nsstringwithformat-swizzled-to-allow-missing-format-numbered-args这基本上是像4号,但没有那么多我自己的引擎作为覆盖 – coneybeare 2010-06-01 00:29:32