使用cJSON解析JSON串时汉字出现多余的'\'
来源:互联网 发布:java静态变量 定义 编辑:程序博客网 时间:2024/06/03 23:44
对于部分特殊的汉字,使用cJSON_AddItemToObject添加键值对后再使用cJSON_Print打印,得到的汉字后面多字符'\'。
跟踪发现解析时对汉字进行了单字节处理导致,应该修改为双字节处理。代码修改如下:
文件:cJSON.c
/* Render the cstring provided to an escaped version that can be printed. */
static char *print_string_ptr(const char *str,printbuffer *p)
{
const char *ptr;char *ptr2,*out;int len=0,flag=0;unsigned char token;
for (ptr=str;*ptr;ptr++) flag|=((*ptr>0 && *ptr<32)||(*ptr=='\"')||(*ptr=='\\'))?1:0;
if (!flag)
{
len=ptr-str;
if (p) out=ensure(p,len+3);
else out=(char*)cJSON_malloc(len+3);
if (!out) return 0;
ptr2=out;*ptr2++='\"';
strcpy(ptr2,str);
ptr2[len]='\"';
ptr2[len+1]=0;
return out;
}
if (!str)
{
if (p) out=ensure(p,3);
else out=(char*)cJSON_malloc(3);
if (!out) return 0;
strcpy(out,"\"\"");
return out;
}
ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
if (p) out=ensure(p,len+3);
else out=(char*)cJSON_malloc(len+3);
if (!out) return 0;
ptr2=out;ptr=str;
*ptr2++='\"';
while (*ptr)
{
int m=strlen(ptr);
if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\')
{
if (*ptr < 0) //汉字需要一次处理2个字节
{
*ptr2++=*ptr++;
*ptr2++=*ptr++;
}
}
else
{
*ptr2++='\\';
switch (token=*ptr++)
{
case '\\': *ptr2++='\\'; break;
case '\"': *ptr2++='\"'; break;
case '\b': *ptr2++='b'; break;
case '\f': *ptr2++='f'; break;
case '\n': *ptr2++='n'; break;
case '\r': *ptr2++='r'; break;
case '\t': *ptr2++='t'; break;
default: sprintf(ptr2,"u%04x",token);ptr2+=5;break;/* escape and print */
}
}
}
*ptr2++='\"';*ptr2++=0;
return out;
}
同样的,JSON串中解析出键值对也需要做特殊处理:
static const char *parse_string(cJSON *item,const char *str)
{
const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
if (*str!='\"') {ep=str;return 0;}/* not a string! */
while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++;/* Skip escaped quotes. */
out=(char*)cJSON_malloc(len+1);/* This is how long we need for the string, roughly. */
if (!out) return 0;
ptr=str+1;ptr2=out;
while (*ptr!='\"' && *ptr)
{
if (*ptr!='\\')
{
if (*ptr < 0)
{
*ptr2++=*ptr++;
}
*ptr2++=*ptr++;
}
else
{
ptr++;
switch (*ptr)
{
case 'b': *ptr2++='\b';break;
case 'f': *ptr2++='\f';break;
case 'n': *ptr2++='\n';break;
case 'r': *ptr2++='\r';break;
case 't': *ptr2++='\t';break;
case 'u': /* transcode utf16 to utf8. */
uc=parse_hex4(ptr+1);ptr+=4;/* get the unicode char. */
if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0)break; /* check for invalid.*/
if (uc>=0xD800 && uc<=0xDBFF)/* UTF16 surrogate pairs. */
{
if (ptr[1]!='\\' || ptr[2]!='u')break; /* missing second-half of surrogate.*/
uc2=parse_hex4(ptr+3);ptr+=6;
if (uc2<0xDC00 || uc2>0xDFFF)break; /* invalid second-half of surrogate.*/
uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));
}
len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
switch (len) {
case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
case 1: *--ptr2 =(uc | firstByteMark[len]);
}
ptr2+=len;
break;
default: *ptr2++=*ptr; break;
}
ptr++;
}
}
*ptr2=0;
if (*ptr=='\"') ptr++;
item->valuestring=out;
item->type=cJSON_String;
return ptr;
}
static const char *parse_string(cJSON *item,const char *str)
{
const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
if (*str!='\"') {ep=str;return 0;}/* not a string! */
while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++;/* Skip escaped quotes. */
out=(char*)cJSON_malloc(len+1);/* This is how long we need for the string, roughly. */
if (!out) return 0;
ptr=str+1;ptr2=out;
while (*ptr!='\"' && *ptr)
{
if (*ptr!='\\')
{
if (*ptr < 0) //汉字需要一次处理两个字节 20171110
{
*ptr2++=*ptr++;
*ptr2++=*ptr++;
}
*ptr2++=*ptr++;
}
else
{
ptr++;
switch (*ptr)
{
case 'b': *ptr2++='\b';break;
case 'f': *ptr2++='\f';break;
case 'n': *ptr2++='\n';break;
case 'r': *ptr2++='\r';break;
case 't': *ptr2++='\t';break;
case 'u': /* transcode utf16 to utf8. */
uc=parse_hex4(ptr+1);ptr+=4;/* get the unicode char. */
if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0)break; /* check for invalid.*/
if (uc>=0xD800 && uc<=0xDBFF)/* UTF16 surrogate pairs. */
{
if (ptr[1]!='\\' || ptr[2]!='u')break; /* missing second-half of surrogate.*/
uc2=parse_hex4(ptr+3);ptr+=6;
if (uc2<0xDC00 || uc2>0xDFFF)break; /* invalid second-half of surrogate.*/
uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));
}
len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
switch (len) {
case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
case 1: *--ptr2 =(uc | firstByteMark[len]);
}
ptr2+=len;
break;
default: *ptr2++=*ptr; break;
}
ptr++;
}
}
*ptr2=0;
if (*ptr=='\"') ptr++;
item->valuestring=out;
item->type=cJSON_String;
return ptr;
}
static const char *parse_string(cJSON *item,const char *str)
{
const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
if (*str!='\"') {ep=str;return 0;}/* not a string! */
while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++;/* Skip escaped quotes. */
out=(char*)cJSON_malloc(len+1);/* This is how long we need for the string, roughly. */
if (!out) return 0;
ptr=str+1;ptr2=out;
while (*ptr!='\"' && *ptr)
{
if (*ptr!='\\')
{
if (*ptr < 0) //汉字需要一次处理两个字节 20171110
{
*ptr2++=*ptr++;
*ptr2++=*ptr++;
}
*ptr2++=*ptr++;
}
else
{
ptr++;
switch (*ptr)
{
case 'b': *ptr2++='\b';break;
case 'f': *ptr2++='\f';break;
case 'n': *ptr2++='\n';break;
case 'r': *ptr2++='\r';break;
case 't': *ptr2++='\t';break;
case 'u': /* transcode utf16 to utf8. */
uc=parse_hex4(ptr+1);ptr+=4;/* get the unicode char. */
if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0)break; /* check for invalid.*/
if (uc>=0xD800 && uc<=0xDBFF)/* UTF16 surrogate pairs. */
{
if (ptr[1]!='\\' || ptr[2]!='u')break; /* missing second-half of surrogate.*/
uc2=parse_hex4(ptr+3);ptr+=6;
if (uc2<0xDC00 || uc2>0xDFFF)break; /* invalid second-half of surrogate.*/
uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));
}
len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
switch (len) {
case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
case 1: *--ptr2 =(uc | firstByteMark[len]);
}
ptr2+=len;
break;
default: *ptr2++=*ptr; break;
}
ptr++;
}
}
*ptr2=0;
if (*ptr=='\"') ptr++;
item->valuestring=out;
item->type=cJSON_String;
return ptr;
}
- 使用cJSON解析JSON串时汉字出现多余的'\'
- 使用cJSON解析JSON字符串
- 使用cJSON解析JSON字符串
- 使用cJSON解析JSON字符串
- 使用cJSON解析JSON字符串
- 使用cJSON解析JSON字符串
- 使用cJSON解析JSON字符串
- JSON学习-使用cJSON解析
- cJSON很好使用的一个json解析器
- cJSON很好使用的一个json解析器
- 有关使用cJSON包解析或者创建JSON时遇到的错误和解决办法
- JSON格式介绍和使用cJSON解析
- 使用cjson库解析json格式
- [转]使用cJSON解析JSON字符串
- cJSON 解析JSON实例
- 使用cJSON库打包json数据及解析json数据
- 使用 CJSON 在C语言中进行 JSON 的创建和解析的实例讲解
- 使用 CJSON 在C语言中进行 JSON 的创建和解析的实例讲解
- linux sed命令详解
- Spring Boot系列(三) Spring Boot 常用注解
- Paint之setXfermode(图形混合模式)
- MongoDbHelper
- 【ML学习笔记】3:机器学习中的数学基础3(特征值,特征向量,认识SVD)
- 使用cJSON解析JSON串时汉字出现多余的'\'
- 源码分析参考:Spider
- 11.3-11.10未一次ac题目(2017)
- Multi tenancy
- 其他题目---KMP算法
- 微信 Tinker 在 Android 中集成以及使用
- Oracle数据库闪回FLASHBACK命令总结
- DateTime格式大全
- MyBatis源码简析