因为项目需要的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(startsizeof(value)) return NULL; } _xpath++; } return ret; } //获取第一个非空白字符. char * json_getfirstcharaddr(char * start,char * end) { while(start=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=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; }