因为项目需要的HTTP协议环境下的JSON数据进行交互.并且本地开发使用C/C++.为了减少工作量自然是需要找几个开源库支持一下.HTTP协议方面CURL即可.JSON方面看起来有不少库可以选择.我找了一个jsoncpp和一个libjson库准备择优录取.
因为JSON格式数据源是JAVA输出的,JSON中的Object集合中的key没有使用双引号结果在jsoncpp和libjson下parse都不能成功.然后我让同事在boost库中有的JSON模式下测试.结果还是不支持没有使用双引号的key.
libjson期待的数据格式:{“key”:”value”},HTTP提供的数据:{key:value}
数据源是第三方软件支持的.没有修改的余地,没有别的办法.我只好自己写这样一个功能:实现一个函数.函数读取并解析JSON串并将所有的集合中的key都加上双引号.并且要求如下.首选函数不能JSON串中的双引号和转义字符干扰.第二.需要支持JSON中的ARRYA,Object的嵌套和混合嵌套.第三不能被空白字符和其它编码干扰.
经过分析和调试.写了一个函数.用来把一个JSON串中的key加上双引号.
此函数可以配合各种C/C++版的JSON使用用于在JSON串中添加和删除双引号.并且函数只用于无格式化的JSON数据.
- // libjsontest.cpp : 定义控制台应用程序的入口点。
- //
- #include “stdafx.h”
- #include “libjson/libjson.h”
- #include “libjson_ext.h”
- #pragma comment(lib,”statLibJson.lib”)
- char * json_getobjtype(char type)
- {
- /*
- #define JSON_NULL ‘/0’
- #define JSON_STRING ‘/1’
- #define JSON_NUMBER ‘/2’
- #define JSON_BOOL ‘/3’
- #define JSON_ARRAY ‘/4’
- #define JSON_NODE ‘/5’*/
- switch(type)
- {
- case ‘/0’:
- return “NULL”;
- case ‘/1’:
- return “STRING”;
- case ‘/2’:
- return “NUMBER”;
- case ‘/3’:
- return “BOOL”;
- case ‘/4’:
- return “ARRAY”;
- case ‘/5’:
- return “NODE”;
- default:
- return “UNDEFINE”;
- }
- }
- //排除引号区域并搜索特殊字符.
- char * json_getcharaddr(char * start,char * end,char key)
- {
- char inq=‘#’;
- char * startbak=start;
- while(start<end)
- {
- if(inq==‘#’&&(*start==‘/’‘||*start==’“‘)&&(start==startbak||*(start-1)!=’//’))
- {
- inq=*start;//进入引区.
- start++;
- continue;
- }
- if(inq!=‘#’&&*start==inq&&*(start-1)!=‘//’)
- {
- inq=‘#’;//退出引区.
- start++;
- continue;
- }
- if(inq==‘#’&&*start==key)return start;//找到了.
- start++;
- }
- return NULL;
- }
- void * json_findnode(void * json,char * xpath)
- {
- char * _xpath=xpath;
- char * xpathend=xpath+strlen(xpath);
- char value[2048];
- unsigned int valueindex=0;
- void * ret=json;
- int ind=0;
- while(_xpath<=xpathend)
- {
- if(*_xpath==‘/’||*_xpath==‘/0’||_xpath==xpathend)
- {
- if(valueindex!=0)
- {
- //printf(“%s/n”,value);
- char * valueend=value+valueindex;
- char * spkey=json_getcharaddr(value,valueend,‘:’);
- char * spkeyold=value;
- if(spkey)
- {
- while(spkey)
- {
- *spkey=‘/0’;
- spkey++;
- ret=::json_get(ret,spkeyold);
- //printf(“%s/n”,spkeyold);
- if(!ret)return NULL;
- if(spkey==valueend)break;
- spkeyold=spkey;
- spkey=json_getcharaddr(spkeyold,valueend,‘:’);
- }
- //printf(“%s/n%s/n/n”,spkeyold,spkey);
- //int size=::json_size(ret);
- //if(size==0);//这里是值并非OBJ或ARR
- if(spkey==NULL)
- {
- ind=atoi(spkeyold);
- //printf(“%s/n”,spkeyold);
- ret=::json_at(ret,ind);
- if(!ret)return NULL;
- }
- }
- else
- {
- ind=atoi(value);
- int size=::json_size(ret);
- if(size==0)return NULL;//这里是值并非OBJ或ARR
- ret=::json_at(ret,ind);
- if(!ret)return NULL;
- }
- }
- memset(value,0,valueindex);
- valueindex=0;
- }
- else
- {
- value[valueindex]=*_xpath;
- valueindex++;
- if(valueindex>sizeof(value))
- return NULL;
- }
- _xpath++;
- }
- return ret;
- }
- //获取第一个非空白字符.
- char * json_getfirstcharaddr(char * start,char * end)
- {
- while(start<end)
- {
- if(!isspace(*start))return start;
- start++;
- }
- return NULL;
- }
- //获取最后一个非空白字符.
- char * json_getlastcharaddr(char * start,char * end)
- {
- end–;
- while(end>=start)
- {
- if(!isspace(*end))return end+1;
- end++;
- }
- return NULL;
- }
- bool json_formatjsonkey(char ** injson,char * injsonend,char ** outjson,char * outjsonmax,bool addq/*=true*/,char split/*=’#’*/)
- {//函数不关心值边界问题.
- //界符:{[,:”‘]}
- //转义:/被转意:”,’,/,/,b,f,n,r,t,u
- //值中不能出现”,/
- //函数在递归时确定injson肯定只包含了一个值.
- char * _injson=*injson;
- char * _outjson=*outjson;
- char _split=‘#’;//默认界符是无界#.找到界,再退出界,然后就返回了.如果没找到界的话.看父界处理.
- //找不到边界就是!按值处理.
- //消除第一个有效字符前的空白字符
- while(_injson<injsonend)//循环条件就是字符串没有处理完.
- {
- if(isspace(*_injson))//在任何情况下都不处理空白字符
- _injson++;
- else
- break;
- }
- if(_injson==injsonend)return false;
- //确定界符.
- if(*_injson==‘[‘||*_injson==‘{‘)
- _split=*_injson;
- else
- _split=‘!’;
- while(_injson<injsonend)//循环条件就是字符串没有处理完.
- {
- if(_outjson>=outjsonmax)return false;
- //_split只可能取值为[,{,!
- switch(_split)
- {
- case ‘[‘:
- //进数组界.
- if(*_injson==‘[‘||*_injson==‘,’)
- {
- *_outjson=*_injson;
- _injson++;
- _outjson++;
- if(!json_formatjsonkey(&_injson,injsonend,&_outjson,outjsonmax,addq,_split))
- return false;
- *injson=_injson;
- *outjson=_outjson;//指针因为函数的执行而向前跳越.
- }
- else if(*_injson==‘]’)
- {
- //出界.进入父界.
- *_outjson=*_injson;
- _injson++;
- _outjson++;
- *injson=_injson;
- *outjson=_outjson;
- *_outjson=‘/0’;
- return true;//递归返回点.
- }
- else
- {
- _injson++;
- }
- break;
- case ‘{‘:
- //进对象界.
- if(*_injson==‘{‘||*_injson==‘,’)
- {
- *_outjson=*_injson;
- _injson++;
- _outjson++;
- //进行KEY处理
- char *tmp=json_getcharaddr(_injson,injsonend,‘:’);
- if(tmp==NULL)return false;//没找到KEY的边界.
- char * keyfirst=json_getfirstcharaddr(_injson,tmp);
- char * keyend=json_getlastcharaddr(keyfirst,tmp);
- int tmplen=keyend-keyfirst;
- bool needq=*keyfirst!=‘”‘;
- if(addq)
- {
- if(needq)
- {
- *_outjson=‘/”‘;
- _outjson++;
- }
- memcpy(_outjson,keyfirst,tmplen);
- _outjson+=tmplen;
- _injson=tmp;
- if(needq)
- {
- *_outjson=‘/”‘;
- _outjson++;
- }
- }
- else
- {
- if(!needq)
- {
- keyfirst++;
- tmplen-=2;
- }
- memcpy(_outjson,keyfirst,tmplen);
- _outjson+=tmplen;
- _injson=tmp;
- }
- //进行值处理
- *_outjson=*_injson;
- _injson++;
- _outjson++;
- if(!json_formatjsonkey(&_injson,injsonend,&_outjson,outjsonmax,addq,_split))
- return false;
- *injson=_injson;
- *outjson=_outjson;//指针因为函数的执行而向前跳越.
- }
- else if(*_injson==‘}’)
- {
- //出界.进入父界.
- *_outjson=*_injson;
- _injson++;
- _outjson++;
- *injson=_injson;
- *outjson=_outjson;
- *_outjson=‘/0’;
- return true;//递归返回点.
- }
- else
- {
- _injson++;
- }
- break;
- case ‘!’:
- switch(split)
- {//如果认定当前内容非ARRAY也非OBJ的话.以父内容来定界.
- case ‘[‘:
- if(*_injson==‘]’||*_injson==‘,’)
- {
- //出界.进入父界.
- *_outjson=*_injson;
- *injson=_injson;
- *outjson=_outjson;
- return true;//递归返回点.
- }
- else
- {
- *_outjson=*_injson;
- _injson++;
- _outjson++;
- continue;
- }
- break;
- case ‘{‘:
- if(*_injson==‘}’||*_injson==‘,’)
- {
- //出界.进入父界.
- *_outjson=*_injson;
- *injson=_injson;
- *outjson=_outjson;
- return true;//递归返回点.
- }
- else
- {
- *_outjson=*_injson;
- _injson++;
- _outjson++;
- continue;
- }
- break;
- default:
- return false;
- }
- break;
- default:
- return false;
- }
- }
- return false;
- }
版权声明:本文为博主原创文章,未经博主允许不得转载。