解决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 ...
随机推荐
- React Native 接入微博、微信、QQ 登录功能
在 App 开发中我们经常需要在用户登录模块接入 SNS 登录组件,这样会大大提高用户的注册体验.特别当一个不是刚性需求 App 推广的时候,这样会很大的降低用户体验的成本,没有人愿意忍受输入邮箱.手 ...
- Java链栈
package com.lxm.customDataStructure; public class LinkStack<T>{ class Node<T>{ T data; N ...
- transformClassesWithDexForDebug
转自:http://blog.sina.com.cn/s/blog_6f3828770102w30b.html
- 设置 github 帐号user.name和邮箱user.email
git config --global user.name username git config --global user.email username@email.com
- [分类算法] :朴素贝叶斯 NaiveBayes
1. 原理和理论基础(参考) 2. Spark代码实例: 1)windows 单机 import org.apache.spark.mllib.classification.NaiveBayes im ...
- python3的基础练习题
1. 执行 Python 脚本的两种方式 1)/usr/bin/python3 xx.py 2)python3 xx.py #注xx.py需要在内容里面调用由什么解释器执行 2. 简述位.字节的关系 ...
- 各种HTTP状态的含义
在网站建设的实际应用中,容易出现很多小小的失误,就像MySQL当初优化不到位,影响整体网站的浏览效果一样,其实,网站的常规http状态码的表现也是一样,Google无法验证网站几种解决办法,提及到由于 ...
- 【类库】容器对象(List、DataTable、 DataView、Dictionary)
首先申明一下,写此博文的目的是纪录一下,知识都是现成的,只是整理一下,为了让自己更容易看懂,比在其他地方更容易明白.因为它们太常用了,不忍心每次都去用那么长的时间查看MSDN,希望能在这里用理少的时间 ...
- 浅谈Android下的Bitmap之大Bitmap加载
引言 我们常常提到的“Android程序优化”,通常指的是性能和内存的优化,即:更快的响应速度,更低的内存占用.Android程序的性能和内存问题,大部分都和图片紧密相关,而图片的加载在很多情况下很用 ...
- 深入理解javascript原型和闭包(16)——完结
之前一共用15篇文章,把javascript的原型和闭包. 首先,javascript本来就“不容易学”.不是说它有多难,而是学习它的人,往往都是在学会了其他语言之后,又学javascript.有其他 ...