5

Apple のString Format Specifiersドキュメントの主張、

NSString フォーマット メソッドと CFString フォーマット関数でサポートされるフォーマット指定子は、IEEE printf 仕様に従います。… これらのフォーマット指定子は NSLog 関数でも使用できます。

ただし、printf仕様では と の同等物として定義さ%Cれていますが、 と のみがとで正しく機能するように見えます。%lc%S%ls%C%SNSLog+[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_tされるintため、現在サポートされているすべてのアーキテクチャで 4 バイト (32 ビット) です。

お気づきのように、printf(3) マンページでは、いくつかの文字 ( )へのポインターを取る%Sと同等であると定義されています。%lswchar_twchar_t *

ただし、リンク先の Cocoa ドキュメント (およびそれに相当する CF) では、次のように%S個別に定義されています。

  • %S: 16 ビットUnicode 文字のヌル終了配列

強調が追加されました。また、同様です%C

したがって、これはバグではありません。CF と Cocoa は、そのいとこがそれらをどのように解釈するかとは異なる方法で解釈し%Sます%CprintfCF と Cocoa は文字を UTF-16として扱いますが、 printf(おそらく) UTF-32 として扱います。

UniCharCF/Cocoa の解釈は、一部の API (ファイル マネージャーなど) がCFString ではなく の配列としてテキストを渡すため、コア サービスを使用する場合により便利です。その配列をnullで終了する限り、それを使用し%Sて文字列を出力できます。

于 2009-03-21T05:25:04.417 に答える