格式说明符(如%15 @)可在NSLog中使用,但不适用于NSString stringWithFormat

时间:2019-05-01 20:50:19

标签: objective-c nslog format-specifiers stringwithformat

当尝试将宽度说明符与%@一起使用时,我发现了一些奇怪的地方。它们可以在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 |

如果我将其更改为使用%scStringUsingEncoding:,那么它将起作用:

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

结果与NSLog相同。

真正使它感到奇怪的是,NSLog基本上只是NSString stringWithFormat:的包装。

那为什么会有不同的结果呢?为什么%@中的stringWithFormat不能使用格式说明符,却与NSLog一起使用?

作为旁注,Swift String init(format:)初始化程序在%@和宽度说明符上也存在相同的问题。

1 个答案:

答案 0 :(得分:0)

谜团是%15@永远奏效的原因。不应该。

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

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