У меня есть эта отформатированная строка, что у меня есть переводчик, продолжают работать.
АНГЛИЙСКИЙ ЯЗЫК
"Check out the %1$@ %2$@ in %3$@: %4$@" = "Check out the %1$@ %2$@ in %3$@: %4$@"
НЕМЕЦКИЙ ПЕРЕВОД
"Check out the %1$@ %2$@ in %3$@: %4$@" = "Hör Dir mal %2$@ in %3$@ an: %4$@";
Они передаются a [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;
С желаемым и фактическим результатом:
АНГЛИЙСКИЙ ЯЗЫК
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"
НЕМЕЦКИЙ ЯЗЫК
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:]
, Я мог сделать вещи как это, где %1$@
переменная полностью опущена. Если Вы замечаете, немецкий перевод строки формата не использует первый аргумент (%1$@
) вообще, но это ("звук") все еще появляется в выходной строке.
Что я делаю неправильно?
Это не ошибка. Пронумерованные аргументы не являются частью стандарта C, но являются частью IEEE Std 1003.1, в котором говорится следующее (выделено мной):
Формат может содержать либо спецификации преобразования нумерованных аргументов (то есть «% n $» и «*»). m $ ") или спецификации преобразования ненумерованных аргументов (то есть% и *), но не то и другое вместе. Единственным исключением является то, что %% можно смешивать с формой "% n $". Результаты смешивания нумерованных и ненумерованных спецификаций аргументов в строке формата не определены. Когда используются спецификации пронумерованных аргументов, указание N-го аргумента требует, чтобы все ведущие аргументы, от первого до (N-1) -го, были указаны в строке формата.
Похоже на ошибку. Я думаю, вам следует подать заявку на ошибку.
Механизм форматирования CFString независим от механизма fprintf
, поэтому могут быть некоторые различия. Например,
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
пропускает 4 байта на 1 пропущенный спецификатор, а форматтер CFString пропускает 0 байт.
Решения следующие:
Перестановка индексов, например,
"Check out the %4$@ %1$@ in %2$@: %3$@".
"Hör Dir mal %1$@ in %2$@ an: %3$@";
или
использовать формат
[@"%1$10p%2$10p%3$10p%4$10p" stringByAppendingString:frmt]
чтобы заставить использовать все аргументы, а затем вырезать первые 40 символов с помощью -substringFromIndex:
, или
Преобразовать все объекты ObjC в строки C (char*
) и использовать snprintf
.