7

翻訳者に作業を依頼しているこのフォーマットされた文字列があります。

英語

"%3$@ の %1$@ %2$@ をチェック: %4$@" = "%3$@ の %1$@ %2$@ をチェック: %4$@"

ドイツ語翻訳

"%3$@ の %1$@ %2$@ をチェックしてください: %4$@" = "Hör Dir mal %2$@ in %3$@ an: %4$@";

[NSString stringWithFormat:]これらは呼び出しに渡されます。

//////////////////////////////////////
// Share Over Twitter
NSString *frmt = NSLocalizedString(@"Check out the %1$@ %2$@ in %3$@: %4$@", @"The default tweet for sharing sounds. Use %1$@ for where the sound type (Sound, mix, playlist) will be, %2$@ for where the audio name will be, %3$@ for the app name, and %3$@ 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;

望ましい結果と実際の結果:

英語

望ましい: "私のアプリ名: link_to_sound でサウンド "このサウンド名" をチェックしてください"
actual: "My App Name: link_to_sound でサウンド "This Sound Name" を確認してください"

ドイツ人

望ましい: "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:]ているこのようなことができる という仮定の下にあったことです。%1$@お気付きかもしれませんが、フォーマット文字列のドイツ語翻訳では、最初の引数 ( %1$@) はまったく使用されていませんが、出力文字列にはそれ (「サウンド」) が表示されます。

私は何を間違っていますか?

4

2 に答える 2

7

これはバグではありません。番号付き引数は C 標準の一部ではありませんが、IEEE Std 1003.1 の一部です。

format には、番号付き引数の変換指定 (つまり、"%n$" と "*m$") または番号なし引数の変換指定 (つまり、 % と * ) のいずれかを含めることができますが、両方を含めることはできません。これに対する唯一の例外は、%% が "%n$" 形式と混在できることです。フォーマット文字列に番号付き引数と番号なし引数を混在させた場合の結果は未定義です。番号付き引数指定を使用する場合、N 番目の引数を指定するには、最初から (N-1) 番目までのすべての先行引数をフォーマット文字列で指定する必要があります。
于 2010-06-01T01:51:36.460 に答える
0

私にはバグのように見えます。バグを報告する必要があると思います

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 OSprintfは1つの欠落している指定子で4バイトをスキップし、CFStringのフォーマッタは0バイトをスキップします。


解決策は次のとおりです。

  1. インデックスを再配置します。例:

    "Check out the %4$@ %1$@ in %2$@: %3$@"
    "Hör Dir mal %1$@ in %2$@ an: %3$@";
    

    また

  2. フォーマットを使用する

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

    すべての引数を強制的に使用してから、最初の40文字を-substringFromIndex:、またはで切り取ります。

  3. すべてのObjCオブジェクトをC文字列(char*)に変換し、を使用しますsnprintf

  4. 独自のフォーマットエンジンを作成します。
于 2010-05-31T16:27:47.053 に答える