// 字符串轉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)*16); NSData *content=[NSData dataWithBytes:tempData length:16];
在使用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
|
|
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編碼,請自行對對應照編碼協議轉換。