// 字符串转Data
NSString *str =@"jesfds";
NSData *data =[str dataUsingEncoding:NSUTF8StringEncoding];
//NSData 转NSString
NSString *result =[[ NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; //data 转char
NSData *data;
char *test=[data bytes]; // char 转data
byte* tempData = malloc(sizeof(byte)*);
NSData *content=[NSData dataWithBytes:tempData length:];

在使用initWithData等方法将NSData转换成NSString时,如果NSData的内容含有非encoding编码的字符,将会返回nil。

----------SDK文档如下-------------

- (instancetype)initWithData:(NSData *)data encoding:(NSStringEncoding)encoding;

Return Value

An NSString object initialized by converting the bytes in data into Unicode characters using encoding. The returned object may be different from the original receiver. Returns nil if the initialization fails for some reason (for example if data does not represent valid data for encoding).

-----------------------------

这个结果在很多时候可能并不是我们所希望的,比如在获取网页源码进行分析等方面,如果页面采用了utf-8编码,只是含有个别非utf-8字符,我们更希望转换NSString成功,抛弃(或替换)那些非法字符。

按照utf8格式标准

Unicode/UCS-4
bit数
UTF-8
byte数
范围(16进制)
0000 ~
007F
0~7
0XXX XXXX
1
0x - 7x
0080 ~
07FF
8~11
110X XXXX
10XX XXXX
2
Cx 8x - Dx Bx
0800 ~
FFFF
12~16
1110XXXX
10XX XXXX
10XX XXXX
3
Ex 8x 8x - Ex Bx Bx
1 0000 ~
1F FFFF
17~21
1111 0XXX
10XX XXXX
10XX XXXX
10XX XXXX
4
F8 8x 8x 8x 8x - FB Bx Bx Bx Bx 
20 0000 ~
3FF FFFF
22~26
1111 10XX
10XX XXXX
10XX XXXX
10XX XXXX
10XX XXXX
5
 

FC 8x 8x 8x 8x 8x - FD Bx Bx Bx Bx Bx

 
400 0000 ~
7FFF FFFF
27~31
1111 110X
10XX XXXX
10XX XXXX
10XX XXXX
10XX XXXX
10XX XXXX
6
 

如果一个字节小于0x80,那么他就是一个字符;

如果大于C0小于E0,表示2个字节组成的utf8字符(第一个是110开头的,第二个是10开头的);

如果大于E0小于F0,表示3个字节组成的utf8字符(第一个是1110开头的,第二个是10开头的,第三个是10开头的);

以此类推,如果不符合utf-8规则,则表示一个非法字符,只要替换这样的字符即可。

实现方法如下(此实现可用但不够严谨,如用于工程中建议进行优化):

  1. //替换非utf8字符
  2. //注意:如果是三字节utf-8,第二字节错误,则先替换第一字节内容(认为此字节误码为三字节utf8的头),然后判断剩下的两个字节是否非法;
  3. - (NSData *)replaceNoUtf8:(NSData *)data
  4. {
  5. char aa[] = {'A','A','A','A','A','A'};                      //utf8最多6个字符,当前方法未使用
  6. NSMutableData *md = [NSMutableData dataWithData:data];
  7. int loc = 0;
  8. while(loc < [md length])
  9. {
  10. char buffer;
  11. [md getBytes:&buffer range:NSMakeRange(loc, 1)];
  12. if((buffer & 0x80) == 0)
  13. {
  14. loc++;
  15. continue;
  16. }
  17. else if((buffer & 0xE0) == 0xC0)
  18. {
  19. loc++;
  20. [md getBytes:&buffer range:NSMakeRange(loc, 1)];
  21. if((buffer & 0xC0) == 0x80)
  22. {
  23. loc++;
  24. continue;
  25. }
  26. loc--;
  27. //非法字符,将这个字符(一个byte)替换为A
  28. [md replaceBytesInRange:NSMakeRange(loc, 1) withBytes:aa length:1];
  29. loc++;
  30. continue;
  31. }
  32. else if((buffer & 0xF0) == 0xE0)
  33. {
  34. loc++;
  35. [md getBytes:&buffer range:NSMakeRange(loc, 1)];
  36. if((buffer & 0xC0) == 0x80)
  37. {
  38. loc++;
  39. [md getBytes:&buffer range:NSMakeRange(loc, 1)];
  40. if((buffer & 0xC0) == 0x80)
  41. {
  42. loc++;
  43. continue;
  44. }
  45. loc--;
  46. }
  47. loc--;
  48. //非法字符,将这个字符(一个byte)替换为A
  49. [md replaceBytesInRange:NSMakeRange(loc, 1) withBytes:aa length:1];
  50. loc++;
  51. continue;
  52. }
  53. else
  54. {
  55. //非法字符,将这个字符(一个byte)替换为A
  56. [md replaceBytesInRange:NSMakeRange(loc, 1) withBytes:aa length:1];
  57. loc++;
  58. continue;
  59. }
  60. }
  61. return md;
  62. }

转换后的NSData就可以正确转换为NSString了。

*如果是非utf-8编码,请自行对对应照编码协议转换。

解决NSData转NSString返回nil的问题的更多相关文章

  1. iOS解决NSData转NSString后字符为空

    iOS中,将NSData转NSString的一般方法为[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];但是当dat ...

  2. 为什么有时候NSData转换成NSString的时候返回nil

    为什么有时候NSData转换成NSString的时候返回nil 有时候,NSData明明有值,可是,当转换成NSString的时候,却没有值,现在来进行测试:) -现在提供测试用素材- 源码如下: / ...

  3. 解决 pathForResource 返回 nil的问题

    点击(此处)折叠或打开 NSString* path = [[NSBundle mainBundle] pathForResource:@"sample" ofType:@&quo ...

  4. NSData和NSString 、 NSFileManager

    1 NSData和NSMutableData的基本使用 1.1 问题 NSData类是IOS提供的用于以二进制的形式操作文件数据的类,NSData有两个常用的属性length和bytes,length ...

  5. NSData、NSString 、 NSFileManager

      1 NSData和NSMutableData的基本使用 1.1 问题 NSData类是IOS提供的用于以二进制的形式操作文件数据的类,NSData有两个常用的属性length和bytes,leng ...

  6. ios 数据类型转换 UIImage转换为NSData NSData转换为NSString

    1.UIImage转换为NSData NSData *data;if (UIImagePNGRepresentation(image) == nil) { data = UIImageJPEGRepr ...

  7. NSData NSDate NSString NSArray NSDictionary 相互转换

    // NSData NSDate NSString NSArray NSDictionary json NSString *string = @"hello word"; NSDa ...

  8. NSData NSDate NSString NSArray NSDictionary 相互转化

    //    NSData  NSDate NSString NSArray NSDictionary json NSString *string = @"hello word"; ...

  9. 如何解决结果由block返回情况下的同步问题(转)

    开发中经常会遇到一种简单的同步问题: 系统在获取资源时,采用了block写法,外部逻辑需要的结果是在block回调中返回的 举个例子: 请求获取通讯录权限的系统弹窗 调用系统方法请求通讯录权限: AB ...

随机推荐

  1. Spark环境搭建遇到的问题

    1.始终找不到Hive表的问题 原因:官方编译后的Spark1.2.0+hadoop2.4与hadoop2.4.1不匹配 解决方法有两个: a.将Hadoop2.4.1替换为2.4.0版本 b.重新编 ...

  2. Android四大组件之—— 使用服务进行后台操作

    什么是服务 服务是一个没有可视化界面的组件,它可以在后台长期运行并进行各种操作. 服务的创建 我们只需要继承Service类并实现相应的方法即可创建服务 要想启动服务,还得在AndroidManife ...

  3. python基础-模块

    一.模块介绍                                                                                              ...

  4. 第二次团队作业——预则立&&他山之石

    Deadline: 2016.10.16 22:00pm 一.确立团队选题,建立和初步熟悉团队git的协作方式.项目后续的代码.文档都要通过github增量式管理.实现文档的版本化和增量式管理. 二. ...

  5. CentOS 7.2 安装配置mysql主从服务器

    MySQL官方压缩包安装: 1:下载mysql官方版本,此处以目前最新版本5.7.14为例,下载的64位版本文件为: mysql-5.7.14-linux-glibc2.5-x86_64.tar 2: ...

  6. 快速上手php:使用PhpStrom部署项目

    闲话 上学的时候一直以为可以专注自己的领域,以为与php无缘的,但是这种想法是错误,在完成任务的时候,你不得不使用你不熟悉的语言或者框架.正所谓业务驱动开发,这次接手已经离职的前辈的留下来的项目,最蛋 ...

  7. Geolocation API JavaScript访问用户的当前位置信息

    Geolocation API在浏览器中的实现是navigator.geolocation对象,常用的有以下方法. 1.第一个方法是getCurrentPosition() 调用这个方法就会触发请求用 ...

  8. npm全局安装和本地安装和本地开发安装(npm install --g/--save/--save-dev)

    详细说明参考:http://www.cnblogs.com/PeunZhang/p/5629329.html 我个人理解: 1.全局安装(npm install -g)是为了用命令行,比如在windo ...

  9. spring aop的使用

    使用上次整合的s2sh工程,加入aop的功能.aop(面向切面编程)是一种对oop的完善,比如在进行数据库操作的时候执行方法前或者后加入一条日志记录,使用一个额外的类去做日志操作,让dao类专注地做它 ...

  10. 网站访问量大 怎样优化mysql数据库

    MySQL优化的一些建议,单机MySQL的优化我分为三个部分,一是服务器物理硬件的优化,二是 MySQL安装时的编译优化,三是自身配置文件my.cnf的优化:如果单机的优化也解决不了你的数据库的压力的 ...