libjson支持中文顯示,但要是你使用\u格式的utf8字符串,那解析就會出問題,百度谷歌了好久都沒找到解決方法。後來找到了一篇文章,裏面有提解決方法,但我沒成功。既然知道了問題所在,就本身寫吧。
json
libjson能夠處理UNICODE,但使用了wchar_t,而開發當中大多使用char,這就形成了不少的不兼容。若是不開啓UNICODE,"\uXXXX"之類的字符,libjson會捨棄前2位.ide
問題出在JSONWorker.cpp的SpecialChar函數裏面函數
1
2
3
4
5
6
7
8
9
|
case
JSON_TEXT(
'u'
):
//utf character
{
#ifdef JSON_UNICODE
UTF(pos, res, end);
#else
UTF8(pos,res, end);
#endif
}
break
;
|
UTF8函數
測試
1
2
3
4
5
6
7
8
9
10
11
12
|
json_uchar JSONWorker::UTF8(
const
json_char * & pos,
const
json_char *
const
end) json_nothrow {
JSON_ASSERT_SAFE(((
long
)end - (
long
)pos) > 4, JSON_TEXT(
"UTF will go out of bounds"
),
return
JSON_TEXT(
'\0'
););
#ifdef JSON_UNICODE
++pos;
json_uchar temp = Hex(pos) << 8;
++pos;
return
temp | Hex(pos);
#
else
pos+=3;
return
Hex(pos);
#endif
}
|
這裏能夠看到,若是不開啓JSON_UNICODE,會將"\uXXXX"中的前2位忽略掉了,ASCII固然是正確的,但非ASCII就會出問題了。spa
因而我增長了幾個函數Hex2UTF8,String2Hex,UTF83B,DChar2Short指針
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
std::string Hex2UTF8(
const
json_char* & pos,
const
json_char *
const
end)
{
JSON_ASSERT(*(pos + 1) == JSON_TEXT(
'0'
), JSON_TEXT(
"wide utf character (hihi)"
));
JSON_ASSERT(*(pos + 2) == JSON_TEXT(
'0'
), JSON_TEXT(
"wide utf character (hilo)"
));
//截取字符串
++pos;
int
len=4;
char
* str=(
char
*)
malloc
(len+1);
bzero(str, len+1);
memcpy
(str, pos, len);
str[len]=0;
pos+=3;
//保留原始指針
char
* pstr=str;
std::string rstr;
if
(*pstr==JSON_TEXT(
'u'
)) {
//u
pstr++;
}
else
if
(*pstr==JSON_TEXT(
'\\'
)){
//\u
pstr+=2;
}
char
hexStr[5]={0};
memcpy
(hexStr, pstr, 4);
unsigned
short
hex=String2Hex(hexStr);
if
(hex<0x0800 ||hex>0xFFFF) {
JSON_ASSERT(1, JSON_TEXT(
"now only support hex >0x0800 's utf8 char"
));
return
""
;
}
rstr+=UTF83B(hex);
free
(str);
str=NULL;
return
rstr;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
|
std::string UTF83B(unsigned
short
hex)
{
unsigned
char
hc=((hex&0xF000)>>12);
//取前4位
unsigned
char
mc=((hex & 0x0FC0)>>6);
//取中間6位
unsigned
char
lc=(hex & 0x003F);
//取後6位
char
str[4]={0};
str[0]=(0xE0 | hc);
str[1]=(0x80 | mc);
str[2]=(0x80 | lc);
std::string rstr=str;
return
rstr;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
unsigned
short
String2Hex(
const
json_char* str)
{
unsigned
short
hex=0x0000;
unsigned
short
hi=0;
unsigned
short
lo=0;
unsigned
short
len=
strlen
(str);
if
(len==2) {
lo=DChar2Short(str);
}
else
if
(len==4)
{
hi=DChar2Short(str);
lo=DChar2Short(str+2);
}
hex=(((hi<<8) &0xFF00) |(lo & 0x00FF));
return
hex;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
unsigned
short
Char2Short(json_char c)
{
unsigned
short
ret = 0;
switch
(c) {
case
'A'
:
case
'a'
:
ret = 10;
break
;
case
'B'
:
case
'b'
:
ret = 11;
break
;
case
'C'
:
case
'c'
:
ret = 12;
break
;
case
'D'
:
case
'd'
:
ret = 13;
break
;
case
'E'
:
case
'e'
:
ret = 14;
break
;
case
'F'
:
case
'f'
:
ret = 15;
break
;
default
:
ret = c -
'0'
;
break
;
}
return
ret;
}
|
1
2
3
4
5
6
7
8
9
10
11
|
unsigned
short
DChar2Short(
const
json_char* str)
{
unsigned
short
ret=0;
unsigned
short
hi=0;
unsigned
short
lo=0;
hi=Char2Short(str[0]);
lo=Char2Short(str[1]);
ret=hi*16+lo;
return
ret;
}
|
而後,在SpecialChar函數裏面修改code
1
2
3
4
5
6
7
|
case
JSON_TEXT(
'u'
):
//utf character
#ifdef JSON_UNICODE
UTF(pos, res, end);
#
else
res += Hex2UTF8(pos, end);
#endif
break
;
|
還有就是不能開啓JSON_ESCAPE_WRITES,否則會失效。ci
注:開發
我只是測試了從\uxxxx出來,但沒測試從原字符串轉換到\u。字符串