解决NSData转NSString返回nil的问题
// 字符串转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规则,则表示一个非法字符,只要替换这样的字符即可。
实现方法如下(此实现可用但不够严谨,如用于工程中建议进行优化):
- //替换非utf8字符
- //注意:如果是三字节utf-8,第二字节错误,则先替换第一字节内容(认为此字节误码为三字节utf8的头),然后判断剩下的两个字节是否非法;
- - (NSData *)replaceNoUtf8:(NSData *)data
- {
- char aa[] = {'A','A','A','A','A','A'}; //utf8最多6个字符,当前方法未使用
- NSMutableData *md = [NSMutableData dataWithData:data];
- int loc = 0;
- while(loc < [md length])
- {
- char buffer;
- [md getBytes:&buffer range:NSMakeRange(loc, 1)];
- if((buffer & 0x80) == 0)
- {
- loc++;
- continue;
- }
- else if((buffer & 0xE0) == 0xC0)
- {
- loc++;
- [md getBytes:&buffer range:NSMakeRange(loc, 1)];
- if((buffer & 0xC0) == 0x80)
- {
- loc++;
- continue;
- }
- loc--;
- //非法字符,将这个字符(一个byte)替换为A
- [md replaceBytesInRange:NSMakeRange(loc, 1) withBytes:aa length:1];
- loc++;
- continue;
- }
- else if((buffer & 0xF0) == 0xE0)
- {
- loc++;
- [md getBytes:&buffer range:NSMakeRange(loc, 1)];
- if((buffer & 0xC0) == 0x80)
- {
- loc++;
- [md getBytes:&buffer range:NSMakeRange(loc, 1)];
- if((buffer & 0xC0) == 0x80)
- {
- loc++;
- continue;
- }
- loc--;
- }
- loc--;
- //非法字符,将这个字符(一个byte)替换为A
- [md replaceBytesInRange:NSMakeRange(loc, 1) withBytes:aa length:1];
- loc++;
- continue;
- }
- else
- {
- //非法字符,将这个字符(一个byte)替换为A
- [md replaceBytesInRange:NSMakeRange(loc, 1) withBytes:aa length:1];
- loc++;
- continue;
- }
- }
- return md;
- }
转换后的NSData就可以正确转换为NSString了。
*如果是非utf-8编码,请自行对对应照编码协议转换。
解决NSData转NSString返回nil的问题的更多相关文章
- iOS解决NSData转NSString后字符为空
iOS中,将NSData转NSString的一般方法为[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];但是当dat ...
- 为什么有时候NSData转换成NSString的时候返回nil
为什么有时候NSData转换成NSString的时候返回nil 有时候,NSData明明有值,可是,当转换成NSString的时候,却没有值,现在来进行测试:) -现在提供测试用素材- 源码如下: / ...
- 解决 pathForResource 返回 nil的问题
点击(此处)折叠或打开 NSString* path = [[NSBundle mainBundle] pathForResource:@"sample" ofType:@&quo ...
- NSData和NSString 、 NSFileManager
1 NSData和NSMutableData的基本使用 1.1 问题 NSData类是IOS提供的用于以二进制的形式操作文件数据的类,NSData有两个常用的属性length和bytes,length ...
- NSData、NSString 、 NSFileManager
1 NSData和NSMutableData的基本使用 1.1 问题 NSData类是IOS提供的用于以二进制的形式操作文件数据的类,NSData有两个常用的属性length和bytes,leng ...
- ios 数据类型转换 UIImage转换为NSData NSData转换为NSString
1.UIImage转换为NSData NSData *data;if (UIImagePNGRepresentation(image) == nil) { data = UIImageJPEGRepr ...
- NSData NSDate NSString NSArray NSDictionary 相互转换
// NSData NSDate NSString NSArray NSDictionary json NSString *string = @"hello word"; NSDa ...
- NSData NSDate NSString NSArray NSDictionary 相互转化
// NSData NSDate NSString NSArray NSDictionary json NSString *string = @"hello word"; ...
- 如何解决结果由block返回情况下的同步问题(转)
开发中经常会遇到一种简单的同步问题: 系统在获取资源时,采用了block写法,外部逻辑需要的结果是在block回调中返回的 举个例子: 请求获取通讯录权限的系统弹窗 调用系统方法请求通讯录权限: AB ...
随机推荐
- 【C#】C#容易忽视的错误
1.string 拼接站内存,前提是字符串比较多的时候string 字符串类型拼接占内存,解决方法就是用 StringBuilder和String.Format2.不知道内置的验证数据类型的方法. ; ...
- 1130mysql explain中的type列含义和extra列的含义
很多朋友在用mysql进行调优的时候都肯定会用到explain来看select语句的执行情况,这里简单介绍结果中两个列的含义. 1 type列 官方的说法,说这列表示的是"访问类型" ...
- HTML form 表单
1.id.name的关系 通常我们在写HTML代码时,会给控件指定一个id属性,这个属性只供JS和CSS使用,在表单提交时,它不起任何作用; 在HTML代码中我们会指定不同的value为各个不同的控件 ...
- Windows 10一周年更新正式版官方ISO镜像(1607)
微软已经开始推送Win10一周年更新正式版系统,按照此前预告微软官方网站也同步推出了Win10一周年更新正式版ISO官方镜像下载,版本已经升级到最新的1607,也就是Win10 Build 1607, ...
- Python【第三章】:python 面向对象 (new)
面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以讲多函数中公用的变量封装到对象中) 对象,根据模板创建的实例(即:对象),实 ...
- 大二在CSDN的博客整理
001我为什么想写博客 控制台版2048 version_1.0总结 022 囚徒困境中的均衡-----从一篇经典论文说起 021 模拟退火算法学习(一)-----求解最短连通路径 020 小记一次网 ...
- 在WildFly中运行多个standalone模式的实例
WildFly作为一款优秀的EJB容器,其前身为JBoss AS.JBoss作为一款开源的应用服务器,被广泛的应用在各种项目当中.假设我们现在有这样一个项目,他是以standalone的模式运行在 ...
- python内置函数
python内置函数 官方文档:点击 在这里我只列举一些常见的内置函数用法 1.abs()[求数字的绝对值] >>> abs(-13) 13 2.all() 判断所有集合元素都为真的 ...
- Node.js入门笔记(6):web开发方法
使用node进行web开发 用户上网流程: 表面上看:打开浏览器--输入网址--跳转--上网. 背后的过程是什么呢? http请求网址到指定的主机--服务器接收请求--服务器响应内容到用户浏览器--浏 ...
- 百度编辑器 Ueditor 下拉处增加字体
左百度,添加到同右钉邮那么多: 1.\ueditor\lang\zh-cn\zh-cn.js 文件中找到: ...