【问题标题】:NSData to NString conversion problemNSData 到 NString 的转换问题
【发布时间】:2009-09-12 12:48:26
【问题描述】:

我得到一个作为 NSData 的 HTML 文件,需要提取其中的某些部分。为此,我需要使用 UTF8 编码将其转换为 NSString。问题是这种转换失败,可能是因为 NSData 包含对 UTF8 无效的字节。我试图获取数据的字节数组并对其进行检查,但是每次遇到非 ASCII 字符(例如希伯来字母)时,我都会感到不自在。

我们将不胜感激。

更新:

致 Gordon - 这样生成的 NSData:

    NSData *theData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&theResponse error:&theError];

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

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

返回零

致 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];

}

【问题讨论】:

  • 这个 NSData 是如何生成的?现在听起来问题是您从源代码中混合了编码。另外,当你说转换失败时,你到底是什么意思?您是否收到错误、垃圾输出或其他问题?
  • 听起来你做得对。发布代码以便验证。

标签: iphone encoding utf-8 nsstring nsdata


【解决方案1】:

我知道这是一个老话题,但我今天在寻找解决方案时提出了这个问题。我现在已经解决了,所以我只是将它发布给其他可能会进入此页面寻找解决方案的人。

这是我在异步请求中所做的:

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

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

后来在我使用的 connectionDidFinishLoading 方法中

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

【讨论】:

    【解决方案2】:

    致 Gordon - 这样生成的 NSData:

        NSData *theData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&theResponse error:&theError];
    

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

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

    返回零

    致 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];
    

    }

    【讨论】:

    • 我已将此信息移至问题中,它不应该真的出现在答案中。
    【解决方案3】:

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

    【讨论】:

    • 我检查了 - 它是 UTF8。你会怎么做?
    【解决方案4】:

    我不确定您是否知道,在将数组放入新的 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 边界有问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-27
      • 2014-02-28
      • 1970-01-01
      • 2018-06-26
      • 1970-01-01
      • 2013-06-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多