诸如 `%15@` 之类的格式说明符适用于 NSLog 但不适用于 NSString stringWithFormat

rma*_*ddy 5 objective-c nslog format-specifiers stringwithformat

尝试将宽度说明符与%@. 他们的工作罚款NSLog,但不与NSString stringWithFormat:

例子:

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

NSLog(@"| %15@ | %-15@ |", rightAligned, leftAligned);
Run Code Online (Sandbox Code Playgroud)

你会得到预期的输出:

|             foo | 1               |
Run Code Online (Sandbox Code Playgroud)

但更换NSLogstringWithFormat:

NSString *test = [NSString stringWithFormat:@"| %15@ | %-15@ |", rightAligned, leftAligned];
Run Code Online (Sandbox Code Playgroud)

并且 的值test不正确:

| foo | 1 |
Run Code Online (Sandbox Code Playgroud)

如果我将其更改为使用%scStringUsingEncoding:然后它可以工作:

NSString *test2 = [NSString stringWithFormat:@"| %15s | %-15s |", [rightAligned cStringUsingEncoding:NSUTF8StringEncoding], [leftAligned cStringUsingEncoding:NSUTF8StringEncoding]];
Run Code Online (Sandbox Code Playgroud)

结果与 相同NSLog

真正奇怪的是它NSLog基本上只是NSString stringWithFormat:.

那么为什么会有不同的结果呢?为什么格式说明符不支持%@instringWithFormat但它们是 with NSLog

附带说明一下,SwiftString init(format:)初始化程序与%@和 宽度说明符存在相同的问题。

mat*_*att 1

神秘的是为什么%15@起作用。不应该。

格式说明符来自sprintf没有%@(它只是 Objective-C 的特殊扩展)。就目前stringWithFormat而言,%15s一直都是这么说的;我可以引用 Stack Overflow 的示例,例如NSString stringwithformat: Padding 2 strings withknown length

我猜它只是“有效”,因为它现在os_log在幕后使用;不幸的是,该os_log语法几乎完全没有记录。