繁体   English   中英

打印C字符串时的NSLog()vs printf()(UTF-8)

[英]NSLog() vs printf() when printing C string (UTF-8)

我注意到如果我尝试使用格式说明符“%s”打印包含UTF-8字符串表示的字节数组, printf()会正确但NSLog()会使其乱码(即每个字节)按原样打印,例如“¥”打印为2个字符:“¬•”)。 这很奇怪,因为我一直以为NSLog()只是printf() ,加上:

  1. 第一个参数('format')是Objective-C字符串,而不是C字符串(因此是“@”)。
  2. 前缀的时间戳和应用程序名称。
  3. 新行自动添加到最后。
  4. 打印Objective-C对象的能力(使用格式“%@”)。

我的代码:

NSString* string; 

// (...fill string with unicode string...)

const char* stringBytes = [string cStringUsingEncoding:NSUTF8Encoding];

NSUInteger stringByteLength = [string lengthOfBytesUsingEncoding:NSUTF8Encoding];
stringByteLength += 1; // add room for '\0' terminator

char* buffer = calloc(sizeof(char), stringByteLength);

memcpy(buffer, stringBytes, stringByteLength);

NSLog(@"Buffer after copy: %s", buffer);
// (renders ascii, no matter what)

printf("Buffer after copy: %s\n", buffer);
// (renders correctly, e.g. japanese text)

不知何故,看起来printf()NSLog()更“智能”。 有没有人知道根本原因,以及这个功能是否记录在任何地方? (找不到)

NSLog()stringWithFormat:似乎期望“系统编码”中的%s的字符串(例如我的计算机上的“Mac Roman”):

NSString *string = @"¥";
NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(CFStringGetSystemEncoding());
const char* stringBytes = [string cStringUsingEncoding:enc];
NSString *log = [NSString stringWithFormat:@"%s", stringBytes];
NSLog(@"%@", log);

// Output: ¥

当然,如果某些字符在系统编码中无法表示,则会失败。 我找不到这种行为的官方文档,但可以看到在stringWithFormat:中使用%s stringWithFormat:NSLog()不能可靠地使用任意UTF-8字符串。

如果要检查包含UTF-8字符串的char缓冲区的内容,则可以使用任意字符(使用盒装表达式语法从UTF-8字符串创建NSString ):

NSLog(@"%@", @(utf8Buffer));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM