簡體   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