Apple的字符串格式说明符记录了声明,
NSString格式化方法和CFString格式化函数支持的格式说明符遵循IEEE printf规范 ; ...您也可以将这些格式说明符与NSLog函数一起使用.
但是,尽管printf
规范定义%C
作为等同于%lc
和%S
作为等同于%ls
只%C
和%S
看起来与正常工作NSLog
和+[NSString stringWithFormat:]
.
例如,请考虑以下代码:
#importint 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代码中的错误?
在Mac OS X上,
定义wchar_t
为int
,因此它是所有当前支持的体系结构上的四个字节(32位).
正如您所注意到的,printf
(3)联机帮助页定义%S
为等效于%ls
,它采用指向某些wchar_t
字符(wchar_t *
)的指针.
但是,您链接到的Cocoa文档(及其CF等价物)确实%S
单独定义:
%S
:以空值终止的16位 Unicode字符数组
强调补充说.同样,也是如此%C
.
所以,这不是一个错误.CF和Cocoa解释%S
和%C
不同于printf
它和堂兄弟如何解释它们.CF和Cocoa将字符视为UTF-16,而printf
(可能)将它们视为UTF-32.
在使用Core Services时,CF/Cocoa解释更有用,因为某些API(例如文件管理器)会将文本作为UniChar
s 数组传递,而不是CFString; 只要您终止该数组,就可以使用它%S
来打印字符串.