用NSString解码UTF8

时间:2012-01-13 11:41:54

标签: objective-c ios utf-8

我是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]];

任何人都知道我做错了什么?

1 个答案:

答案 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。