【问题标题】:Why do NSString and NSLog appear to handle %C and %lc (and %S and %ls) differently?为什么 NSString 和 NSLog 似乎以不同的方式处理 %C 和 %lc(以及 %S 和 %ls)?
【发布时间】:2009-03-20 21:02:46
【问题描述】:

Apple 的 String Format Specifiers 文件声称,

NSString格式化方法和CFString格式化函数支持的格式说明符遵循IEEE printf specification; …您还可以将这些格式说明符与 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 代码中的错误?

【问题讨论】:

    标签: cocoa unicode formatting printf


    【解决方案1】:

    在 Mac OS X 上,&lt;machine/_types.h&gt;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。

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

    【讨论】:

    • 谢谢;这很有意义!我想我会在文档中将此描述为一个错误,因为在这种情况下 NSString 格式化方法显然不遵循 printf 规范。这似乎是一个公平的评估?
    • 中等错误;它应该说类似“......,有几个变体”,并在表格中标记它们。该文档确实在表格中正确描述了 CF/Cocoa 的解释,尽管它没有将它们标记为与 printf 的定义不同。
    • 我也是这样描述它的。再次感谢您的帮助!
    猜你喜欢
    • 2016-10-01
    • 2016-02-15
    • 1970-01-01
    • 1970-01-01
    • 2017-02-07
    • 1970-01-01
    • 2023-03-22
    • 2020-09-27
    • 2015-01-05
    相关资源
    最近更新 更多