我正在嘗試實作轉換const char *為NSString. 我想以指定的順序嘗試多種編碼,直到找到一種有效的編碼。不幸的是,如果編碼不起作用,所有initWith...方法NSString都說結果未定義。
特別是,(有時)我想首先嘗試編碼為NSMacOSRomanStringEncoding似乎永遠不會失敗。相反,它只是對 gobbledygook 進行編碼。我可以提前進行某種檢查嗎?(就像canBeConvertedToEncoding但在另一個方向?)
uj5u.com熱心網友回復:
與其一一嘗試編碼直到找到匹配項,不如考慮使用NSString來幫助您,在 [NSString stringEncodingForData:encodingOptions:convertedString:usedLossyConversion:]給定字串資料和一些選項的情況下,它可能能夠為您檢測編碼,并回傳它(連同實際的解碼字串)。
專門針對您的用例,因為您有一個想要嘗試的編碼串列,該encodingOptions引數將允許您使用NSStringEncodingDetectionSuggestedEncodingsKey.
因此,給定一個 C 字串和一些可能的編碼選項,您可能可以執行以下操作:
NSString *decodeCString(const char *source, NSArray<NSNumber *> *encodings) {
NSData * const cStringData = [NSData dataWithBytesNoCopy:(void *)source length:strlen(source) freeWhenDone:NO];
NSString *result = nil;
BOOL usedLossyConversion = NO;
NSStringEncoding determinedEncoding = [NSString stringEncodingForData:cStringData
encodingOptions:@{NSStringEncodingDetectionSuggestedEncodingsKey: encodings,
NSStringEncodingDetectionUseOnlySuggestedEncodingsKey: @YES}
convertedString:&result
usedLossyConversion:&usedLossyConversion];
/* Decide whether to do anything with `usedLossyConversion` and `determinedEncoding. */
return result;
}
用法示例:
NSString *result = decodeCString("Hello, world!", @[@(NSShiftJISStringEncoding), @(NSMacOSRomanStringEncoding), @(NSASCIIStringEncoding)]);
NSLog(@"%@", result); // => "Hello, world!"
如果您不是 100% 關心僅使用您想嘗試的編碼串列,您可以洗掉該NSStringEncodingDetectionUseOnlySuggestedEncodingsKey選項。
關于您傳入的編碼陣列需要注意的一件事:盡管檔案并沒有保證按順序嘗試建議的編碼,但通過(當前)方法實作的反匯編進行深入研究表明該陣列是使用快速列舉(即, 為了)。我可以想象這在未來可能會發生變化(或者過去會有所不同)所以如果這對您來說是一個硬性要求,理論上您可以通過一次重復呼叫 stringEncodingForData:encodingOptions:convertedString:usedLossyConversion:一個編碼來解決它,但這會鑒于這種方法的復雜性,可能會非常昂貴。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/329148.html
