Спецификатор формата, такой как `% 15 @`, работает в NSLog, но не с NSString stringWithFormat - PullRequest
4 голосов
/ 01 мая 2019

Я обнаружил что-то странное при попытке использовать спецификаторы ширины с %@. Они отлично работают в NSLog, но не в NSString stringWithFormat:.

Пример:

NSString *rightAligned = @"foo";
NSString *leftAligned = @"1";

NSLog(@"| %15@ | %-15@ |", rightAligned, leftAligned);

И вы получите ожидаемый результат:

|             foo | 1               |

Но замените NSLog на stringWithFormat::

NSString *test = [NSString stringWithFormat:@"| %15@ | %-15@ |", rightAligned, leftAligned];

И значение test неверно:

| foo | 1 |

Если я изменю это на %s и cStringUsingEncoding:, то это будет работать:

NSString *test2 = [NSString stringWithFormat:@"| %15s | %-15s |", [rightAligned cStringUsingEncoding:NSUTF8StringEncoding], [leftAligned cStringUsingEncoding:NSUTF8StringEncoding]];

Результат такой же, как с NSLog.

Что действительно странно, так это то, что NSLog - это просто оболочка вокруг NSString stringWithFormat:.

Так почему же разные результаты? Почему спецификаторы формата не учитываются для %@ в stringWithFormat, а для NSLog?

Примечание: инициализатор Swift String init(format:) имеет ту же проблему с %@ и спецификаторами ширины.

1 Ответ

0 голосов
/ 08 мая 2019

Загадка в том, почему %15@ будет когда-либо работать.Не должно.

Спецификаторы формата взяты из sprintf, у которого нет %@ (это просто специальное расширение для Objective-C).Что касается stringWithFormat, %15s всегда всегда был способ сказать это;Я могу привести примеры переполнения стека, такие как NSString stringwithformat: заполнение 2 строк неизвестной длины .

Я предполагаю, что это только "работает", потому что теперь оно использует os_log под капотом;к сожалению, синтаксис os_log почти полностью не документирован.

...