5

Apple 的字符串格式说明符文档声明,

NSString 格式化方法和 CFString 格式化函数支持的格式说明符遵循IEEE printf 规范;…您还可以将这些格式说明符与 NSLog 函数一起使用。

但是,虽然printf规范定义%C%lc%S的等价物%ls,但只有%C%S似乎可以与NSLog和一起正常工作+[NSString stringWithFormat:]

例如,考虑以下代码:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    unichar str[3];
    str[0] = 63743;
    str[1] = 33;
    str[2] = (unichar)NULL;

    NSLog(@"NSLog");
    NSLog(@"%%S:  %S", str);
    NSLog(@"%%ls: %ls", str);

    NSLog(@"%%C:  %C", str[0]);
    NSLog(@"%%lc: %lc", str[0]);

    NSLog(@"\n");
    NSLog(@"+[NSString stringWithFormat:]");

    NSLog(@"%%S:  %@", [NSString stringWithFormat:@"%S", str]);
    NSLog(@"%%ls: %@", [NSString stringWithFormat:@"%ls", str]);

    NSLog(@"%%C:  %@", [NSString stringWithFormat:@"%C", str[0]]);
    NSLog(@"%%lc: %@", [NSString stringWithFormat:@"%lc", str[0]]);

    [pool drain];
    return 0;
}

鉴于printf规范,我希望上述每一对都打印相同的东西。但是,当我运行代码时,我得到以下输出:

2009-03-20 17:00:13.363 UnicharFormatSpecifierTest[48127:10b] NSLog
2009-03-20 17:00:13.365 UnicharFormatSpecifierTest[48127:10b] %S:  !
2009-03-20 17:00:13.366 UnicharFormatSpecifierTest[48127:10b] %ls: ˇ¯!
2009-03-20 17:00:13.366 UnicharFormatSpecifierTest[48127:10b] %C:  
2009-03-20 17:00:13.367 UnicharFormatSpecifierTest[48127:10b] %lc: 
2009-03-20 17:00:13.367 UnicharFormatSpecifierTest[48127:10b] 
2009-03-20 17:00:13.368 UnicharFormatSpecifierTest[48127:10b] +[NSString stringWithFormat:]
2009-03-20 17:00:13.368 UnicharFormatSpecifierTest[48127:10b] %S:  !
2009-03-20 17:00:13.369 UnicharFormatSpecifierTest[48127:10b] %ls: ˇ¯!
2009-03-20 17:00:13.369 UnicharFormatSpecifierTest[48127:10b] %C:  
2009-03-20 17:00:13.370 UnicharFormatSpecifierTest[48127:10b] %lc: 

我做错了什么,或者这是Apple代码中的错误?

4

1 回答 1

6

在 Mac OS X 上,<machine/_types.h>定义wchar_tint,因此在所有当前支持的架构上它是四个字节(32 位)。

正如您所注意到的,printf(3) 联机帮助页定义%S为等效于%ls,它接受一个指向某些wchar_t字符 ( wchar_t *) 的指针。

但是,您链接到的 Cocoa 文档(及其 CF 等效文档)确实%S单独定义:

  • %S: 以 Null 结尾的16 位Unicode 字符数组

重点补充。此外,对于%C.

所以,这不是一个错误。CF 和 Cocoa 的解释方式%S与它的表亲对它们的解释%C方式不同。printfCF 和 Cocoa 将字符视为 UTF-16,而printf(可能)将它们视为 UTF-32。

CF/Cocoa 解释在使用核心服务时更有用,因为某些 API(例如文件管理器)会将文本作为UniChars 数组而不是 CFString 传递给您;只要您对该数组进行空终止,就可以使用它%S来打印字符串。

于 2009-03-21T05:25:04.417 回答