NSData转换为NSString的问题!

6

我收到了一个html文件的NSData数据,并需要解析其中的一些信息。我的方法是将其转换为NSString,使用UTF8编码(html中包含非英语字符,例如俄语)- 但是失败了。我尝试了以下代码:

NSString *respData = [NSString stringWithUTF8String:[theData bytes]];

但它返回了nil。

唯一起作用的是

[NSString stringWithCString:[theData bytes] length:[theData length]];

但是当它遇到俄语字符时,例如,它会返回乱码。

然后我的下一个尝试是解析数据的字节数组,提取我需要的字节,然后以某种方式将它们转换为NSString。我尝试了这样的方法:

-(NSString *)UTF8StringFromData:(NSData *)theData{
 Byte *arr = [theData bytes];
 NSUInteger begin1 = [self findIndexOf:@"<li>" bArr:arr size:[theData length]]+4;
 NSUInteger end1 = [self findIndexOf:@"</li></ol>" bArr:arr size:[theData length]];
 Byte *arr1 = (Byte *)malloc(sizeof(Byte)*((end1-begin1+1)));
 int j = 0;
 for (int i = begin1; i < end1; i++){
  arr1[j] = arr[i];
  j++;
 }
 arr1[j]='\0';
 NSData *temp = [NSData dataWithBytes:arr1 length:j];
 return [[NSString alloc] initWithData:temp encoding:NSUTF8StringEncoding];
}

1
你确定这个文件编码是UTF-8,而不是ISO 8859-5或其他编码吗? - Wevah
3个回答

11

假设你获取到了一个NSURLResponse* 类型的response和一个NSData* 类型的data:

CFStringEncoding cfEncoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef) [response textEncodingName]);
NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(cfEncoding);

NSString* string = [[NSString alloc] initWithData:data encoding:encoding];

// Do stuff here..

[string release];

我正在使用启用了ARC的xcode 4进行项目开发,当我使用上述代码时,它会抱怨“将Objective-C指针类型'String *'转换为C指针类型'CFStringRef'(又名'const struct __CFString *')需要桥接转换”。当我实施任何建议的修复措施(使用__bridge__bridge_retained)时,程序运行时会出现EXC_BAD_ACCESS信号。有什么想法吗? - Guss
应该是 (__bridge CFStringRef) [response textEncodingName]。这两者都不起作用,这表明问题出在其他地方。打开 NSZombieEnabled 并使用 CFZombieLevel 来跟踪已释放的内存访问。 - Martijn Thé
谢谢回复。听起来相当复杂,而且我对iOS开发一窍不通,但我会去看看的。最终,我通过使用可怕的代码解决了这个问题:char* myenc = malloc([responseEncoding length]); [[_response textEncodingName] getCString:myenc maxLength:[responseEncoding length] encoding:NSASCIIStringEncoding]; CFStringRef encenc = CFStringCreateWithCString(kCFAllocatorDefault, myenc, kCFStringEncodingASCII); CFStringEncoding cfEncoding = CFStringConvertIANACharSetNameToEncoding(encenc); free(myenc); - Guss

1
我在这里回应Martijn Thé的帖子,因为我无法在评论中放置可读的代码片段。
我发现如果在服务器上,响应内容类型设置为“text/plain”,那么(__bridge CFStringRef)[response textEncodingName]将为空,如果您尝试将其传递给CFStringConvertIANACharSetNameToEncoding,您将收到一个EXC_BAD_ACCESS信号。
如果响应的内容类型设置为“text/html; charset=utf-8”,则一切都按预期工作。要处理“text/plain”内容类型,我做了以下操作:
CFStringRef sRef = (__bridge CFStringRef)[response textEncodingName]; if (sRef) { CFStringEncoding cfEncoding = CFStringConvertIANACharSetNameToEncoding(sRef); encoding = CFStringConvertEncodingToNSStringEncoding(cfEncoding); } else { encoding = NSASCIIStringEncoding; }

0
首先这是我的代码。
-(NSString *)UTF8StringFromData:(NSData *)theData{
    Byte *arr = [theData bytes];
    NSUInteger begin1 = [self findIndexOf:@"<li>" bArr:arr size:[theData length]]+4;
    NSUInteger end1 = [self findIndexOf:@"</li></ol>" bArr:arr size:[theData length]];
    Byte *arr1 = (Byte *)malloc(sizeof(Byte)*((end1-begin1+1)));
    int j = 0;
    for (int i = begin1; i < end1; i++){
        arr1[j] = arr[i];
        j++;
    }
    arr1[j]='\0';
    NSData *temp = [NSData dataWithBytes:arr1 length:j];
    return [[NSString alloc] initWithData:temp encoding:NSUTF8StringEncoding];  
}

其次 - 我正在从网络上获取文件内容 - 所以我不能确定任何东西。如果有帮助的话,它是谷歌翻译的HTML...


没有人知道吗?...得了吧...肯定有人遇到过这个问题。 - Alex1987

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接