我在尝试使用 %@
的宽度指定符时发现了一些奇怪的东西。它们在NSLog
中正常工作,但在NSString stringWithFormat:
中不正常。
示例:
NSString *rightAligned = @"foo";
NSString *leftAligned = @"1";
NSLog(@"| %15@ | %-15@ |", rightAligned, leftAligned);
您将获得:
的预期输出| foo | 1 |
但用stringWithFormat:
替换NSLog
:
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:)
初始化器与%@
和宽度指定符具有相同的问题。
这个谜就是为什么 %15@
会 ever 工作。它不应该。
格式指定符来自没有%@
的sprintf
(它只是Objective-C的特殊扩展(。就 stringWithFormat
而言, %15s
始终是这样说的方法。我可以引用堆栈 溢出示例,例如nsstring stringwithformat:padding 2带有未知长度的字符串。
我猜它只是"工作",因为它现在使用引擎盖下的os_log
;不幸的是,os_log
语法几乎完全没有证明。