6

J'ai cette chaîne formatée sur laquelle travaille un traducteur.Localisation avancée avec omission d'arguments dans Xcode

ANGLAIS

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

TRADUCTION ALLEMAND

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

Ceux-ci sont transmis à un appel [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; 

Avec le choix et le résultat réel de:

ANGLAIS

 
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" 

ALLEMAND

 
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" 



LE PROBLÈME Le problème est que je suis sous l'hypothèse qu'en utilisant la variable numérotée dans la -[NSString stringWithFormat:], Je pourrais faire ça ngs comme ceci, où la variable %[email protected] est complètement omise. Si vous remarquez, la traduction allemande de la chaîne de format n'utilise pas le premier argument (%[email protected]) mais elle ("son") apparaît toujours dans la chaîne de sortie.

Qu'est-ce que je fais mal?

Répondre

7

Ce n'est pas un bug. Les arguments numérotés ne font pas partie du standard C, mais font partie de la norme IEEE 1003.1, qui dit ce qui suit (emphase mienne):

Le format peut contenir des spécifications de conversion d'argument numérotées (c'est-à-dire, "% n $" et " * m $ "), ou des spécifications de conversion d'argument non numérotées (c'est-à-dire% et *), mais pas les deux. La seule exception à ceci est que %% peut être mélangé avec le formulaire "% n $". Les résultats du mélange de spécifications d'argument numérotées et non numérotées dans une chaîne de format ne sont pas définis. Lorsque des spécifications d'argument numérotées sont utilisées, la spécification du Nième argument nécessite que tous les arguments principaux, du premier au (N-1) e, soient spécifiés dans la chaîne de format.
+0

il semble que ce que je faisais mal est de faire une hypothèse sur l'omission de variables numérotées. – coneybeare

+0

Il est intéressant que cela fonctionne bien dans Android/Java; doit être leur implémentation (invalide?) – Opus1217

0

On dirait un bug pour moi. Je pense que vous devriez déposer un bug.

Le moteur de formatage de CFString est indépendant de fprintf, donc il pourrait y avoir quelques différences. Par exemple,

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

Vous devez fournir tous les spécificateurs précédentes parce que la largeur d'un argument n'a pas besoin d'être fixé, par exemple

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 skips 4 octets sur 1 spécificateur manquant, et le formateur de CFString saute 0 octets.


Les solutions sont:

  1. réorganisez vos indices, par exemple

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

    ou

  2. utiliser le format

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

    pour forcer tous les arguments à utiliser, puis couper les 40 premiers caractères avec -substringFromIndex:, ou

  3. Convertir tous ObjC objets dans les chaînes C (char*) et utiliser snprintf.

  4. Écrivez votre propre moteur de formatage.
+0

J'espérais éviter ces solutions de contournement et renvoyer les fichiers aux traducteurs. booooo – coneybeare

+0

Pouvez-vous expliquer ce que fait le numéro 2? – coneybeare

+0

J'ai essayé d'implémenter une 5ème option, ici: http://stackoverflow.com/questions/2946649/nsstringwithformat-swizzled-to-allow-missing-format-numbered-args qui est essentiellement comme le numéro 4, mais pas tellement de mon propre moteur comme remplacement – coneybeare