NSData转换为NSString的问题

5
我收到了一个HTML文件的NSData,并需要提取其中的一些部分。为此,我需要使用UTF8编码将其转换为NSString。问题是这种转换失败了,可能是因为NSData包含了对于UTF8无效的字节。我尝试获取数据的字节数组并遍历它,但每次遇到非ASCII字符(例如希伯来字母)时,我都会得到乱码。
需要帮助,谢谢。
更新:
对于Gordon - 生成的NSData如下:
    NSData *theData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&theResponse error:&theError];

当我说转换失败时,我的意思是
[[NSString alloc] initWithData:temp encoding:NSUTF8StringEncoding]

返回 nil

给 Ed - 这是我的代码(我从 NSData 得到了 Byte 数组,找到了需要的内容,并从中构建了另一个 Byte 数组 - 将其转换为 NSData,然后尝试将其转换为 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)));
NSLog(@"%d %d",begin1, end1);
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
这个NSData是如何生成的?现在看起来问题是源文件中编码混乱。另外,当你说转换失败时,具体指什么?你是否收到错误信息、垃圾输出或其他内容? - Gordon Seidoh Worley
听起来你做得很对。请发布代码以便进行验证。 - Ed Marty
4个回答

6

我知道这是一个老话题,但当我今天寻找解决方案时它出现了。我已经解决了问题,所以我只是为那些可能在寻找解决方案的人发布它。

以下是我在异步请求中的做法:

首先,我使用connection:didReceiveResponse将文本编码名称存储在连接中:

encodingName = [[NSString alloc] initWithString:[response textEncodingName]];

后来在我的connectionDidFinishLoading方法中,我使用了以下代码:

NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((CFStringRef) encodingName));
NSString *payloadAsString = [[NSString alloc] initWithData:receivedData encoding:encoding];

0
给Gordon - 生成的NSData就像这样:
    NSData *theData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&theResponse error:&theError];

当我说转换失败时,我的意思是

[[NSString alloc] initWithData:temp encoding:NSUTF8StringEncoding]

返回 nil

给 Ed - 这是我的代码(我从 NSData 获取了 Byte 数组,找到需要的内容,并从中构建了另一个 Byte 数组 - 将其转换为 NSData,然后尝试将其转换为 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)));
NSLog(@"%d %d",begin1, end1);
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];

}


我已经将这些信息移动到问题中,它不应该出现在答案中。 - Logan Capaldo

0

我不确定你是否知道,将数组复制到另一个数组中再放入新的NSData对象之前其实是不必要的。

-(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 = arr + begin1;
  NSData *temp = [NSData dataWithBytes:arr1 length:end1 - begin1];
  return [[NSString alloc] initWithData:temp encoding:NSUTF8StringEncoding];
}

关于您的特定问题,我建议您使用调试器手动查看数据。在您拥有数组(arr1)之后设置断点。当您触发它时,打开GDB控制台并尝试以下操作:
print (char *)arr1

使用您的代码,它应该打印出您想要获取的字符串。(使用我上面给出的代码,它不会在点号后停止。它将继续执行)。

如果结果与您预期的不同,则数据可能存在问题,或者您的begin1end1边界存在问题。


0

你有检查HTTP头和/或文档本身中的charset=吗?转换失败的最可能原因是字节不代表有效的UTF-8字符串。


我已经检查过了 - 它是UTF8编码。你会怎样做? - Alex1987

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