我是Objective-C的新手,并尝试使用apples docs上的示例将格式错误的UTF8编码的NSString转换为格式良好的NSString。
NSString *theString = @"Lügen"; //should be "ü"
NSString *asciiString = [[NSString alloc] initWithData:asciiData encoding:NSASCIIStringEncoding];
NSLog(@"Original: %@ (length %d)", theString, [theString length]);
NSLog(@"Converted: %@ (length %d)", asciiString, [asciiString length]);
结果:
Original: Lügen (length 6)
Converted: LA1/4gen (length 8)
这里什么都不做:
NSString* str = [NSString stringWithUTF8String:
[theString cStringUsingEncoding:NSASCIIStringEncoding]];
这会崩溃我的应用
NSString* str = [NSString stringWithUTF8String:
[theString cStringUsingEncoding:NSUTF8StringEncoding]];
任何人都知道我做错了什么?
答案 0 :(得分:14)
NSString *string = @"ü";
const char *c = [string cStringUsingEncoding:NSISOLatin1StringEncoding];
NSString *newString = [[NSString alloc]initWithCString:c encoding:NSUTF8StringEncoding];
NSLog(@"%@",newString); // ü
“格式错误的UTF-8序列”表示在UTF-8中无效的字节序列。在使用与字符串原始作者使用的编码不同的编码解析字符串后,您的问题是意外结果。
使用UTF-8编码的十六进制数据C3 BC
已解析是字符ü
。相反,您使用的是Latin-1编码,结果为ü
。然后你从Latin-1解析字符串创建了一个NSString,这意味着你将拉丁文-1字符串转换为UTF-16字符串(这是NSString的原生格式)。
以不同的编码表示给定数据会显示为不同的字符,但不会更改数据。转换为不同的编码会更改数据以尝试重现相同的字符。示例:字符ü
在UTF-8中为C3 83 C2 BC
,但在Latin-1中为C3 BC
。所以我在Latin-1中转换为相同的字符以获取原始数据,然后我将其解析为UTF-8。