给JSON数据字符串中的键名加上双引号

因为项目需要的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数据.

 

  1. // libjsontest.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include “stdafx.h”
  4. #include “libjson/libjson.h”
  5. #include “libjson_ext.h”
  6. #pragma comment(lib,”statLibJson.lib”)
  7. char * json_getobjtype(char type)
  8. {
  9.     /*
  10.     #define JSON_NULL ‘/0’
  11. #define JSON_STRING ‘/1’
  12. #define JSON_NUMBER ‘/2’
  13. #define JSON_BOOL ‘/3’
  14. #define JSON_ARRAY ‘/4’
  15. #define JSON_NODE ‘/5’*/
  16.     switch(type)
  17.     {
  18.     case ‘/0’:
  19.         return “NULL”;
  20.     case ‘/1’:
  21.         return “STRING”;
  22.     case ‘/2’:
  23.         return “NUMBER”;
  24.     case ‘/3’:
  25.         return “BOOL”;
  26.     case ‘/4’:
  27.         return “ARRAY”;
  28.     case ‘/5’:
  29.         return “NODE”;
  30.     default:
  31.         return “UNDEFINE”;
  32.     }
  33. }
  34. //排除引号区域并搜索特殊字符.
  35. char * json_getcharaddr(char * start,char * end,char key)
  36. {
  37.     char inq=‘#’;
  38.     char * startbak=start;
  39.     while(start<end)
  40.     {
  41.         if(inq==‘#’&&(*start==‘/’‘||*start==’‘)&&(start==startbak||*(start-1)!=’//’))
  42.         {
  43.             inq=*start;//进入引区.
  44.             start++;
  45.             continue;
  46.         }
  47.         if(inq!=‘#’&&*start==inq&&*(start-1)!=‘//’)
  48.         {
  49.             inq=‘#’;//退出引区.
  50.             start++;
  51.             continue;
  52.         }
  53.         if(inq==‘#’&&*start==key)return start;//找到了.
  54.         start++;
  55.     }
  56.     return NULL;
  57. }
  58. void * json_findnode(void * json,char * xpath)
  59. {
  60.     char * _xpath=xpath;
  61.     char * xpathend=xpath+strlen(xpath);
  62.     char value[2048];
  63.     unsigned int valueindex=0;
  64.     void * ret=json;
  65.     int ind=0;
  66.     while(_xpath<=xpathend)
  67.     {
  68.         if(*_xpath==‘/’||*_xpath==‘/0’||_xpath==xpathend)
  69.         {
  70.             if(valueindex!=0)
  71.             {
  72.                 //printf(“%s/n”,value);
  73.                 char * valueend=value+valueindex;
  74.                 char * spkey=json_getcharaddr(value,valueend,‘:’);
  75.                 char * spkeyold=value;
  76.                 if(spkey)
  77.                 {
  78.                     while(spkey)
  79.                     {
  80.                         *spkey=‘/0’;
  81.                         spkey++;
  82.                         ret=::json_get(ret,spkeyold);
  83.                         //printf(“%s/n”,spkeyold);
  84.                         if(!ret)return NULL;
  85.                         if(spkey==valueend)break;
  86.                         spkeyold=spkey;
  87.                         spkey=json_getcharaddr(spkeyold,valueend,‘:’);
  88.                     }
  89.                     //printf(“%s/n%s/n/n”,spkeyold,spkey);
  90.                     //int size=::json_size(ret);
  91.                     //if(size==0);//这里是值并非OBJ或ARR
  92.                     if(spkey==NULL)
  93.                     {
  94.                         ind=atoi(spkeyold);
  95.                         //printf(“%s/n”,spkeyold);
  96.                         ret=::json_at(ret,ind);
  97.                         if(!ret)return NULL;
  98.                     }
  99.                 }
  100.                 else
  101.                 {
  102.                     ind=atoi(value);
  103.                     int size=::json_size(ret);
  104.                     if(size==0)return NULL;//这里是值并非OBJ或ARR
  105.                     ret=::json_at(ret,ind);
  106.                     if(!ret)return NULL;
  107.                 }
  108.             }
  109.             memset(value,0,valueindex);
  110.             valueindex=0;
  111.         }
  112.         else
  113.         {
  114.             value[valueindex]=*_xpath;
  115.             valueindex++;
  116.             if(valueindex>sizeof(value))
  117.                 return NULL;
  118.         }
  119.         _xpath++;
  120.     }
  121.     return ret;
  122. }
  123. //获取第一个非空白字符.
  124. char * json_getfirstcharaddr(char * start,char * end)
  125. {
  126.     while(start<end)
  127.     {
  128.         if(!isspace(*start))return start;
  129.         start++;
  130.     }
  131.     return NULL;
  132. }
  133. //获取最后一个非空白字符.
  134. char * json_getlastcharaddr(char * start,char * end)
  135. {
  136.     end–;
  137.     while(end>=start)
  138.     {
  139.         if(!isspace(*end))return end+1;
  140.         end++;
  141.     }
  142.     return NULL;
  143. }
  144. bool json_formatjsonkey(char ** injson,char * injsonend,char ** outjson,char * outjsonmax,bool addq/*=true*/,char split/*=’#’*/)
  145. {//函数不关心值边界问题.
  146.     //界符:{[,:”‘]}
  147.     //转义:/被转意:”,’,/,/,b,f,n,r,t,u
  148.     //值中不能出现”,/
  149.     //函数在递归时确定injson肯定只包含了一个值.
  150.     char * _injson=*injson;
  151.     char * _outjson=*outjson;
  152.     char _split=‘#’;//默认界符是无界#.找到界,再退出界,然后就返回了.如果没找到界的话.看父界处理.
  153.     //找不到边界就是!按值处理.
  154.     //消除第一个有效字符前的空白字符
  155.     while(_injson<injsonend)//循环条件就是字符串没有处理完.
  156.     {
  157.         if(isspace(*_injson))//在任何情况下都不处理空白字符
  158.             _injson++;
  159.         else
  160.             break;
  161.     }
  162.     if(_injson==injsonend)return false;
  163.     //确定界符.
  164.     if(*_injson==‘[‘||*_injson==‘{‘)
  165.         _split=*_injson;
  166.     else
  167.         _split=‘!’;
  168.     while(_injson<injsonend)//循环条件就是字符串没有处理完.
  169.     {
  170.         if(_outjson>=outjsonmax)return false;
  171.         //_split只可能取值为[,{,!
  172.         switch(_split)
  173.         {
  174.         case ‘[‘:
  175.             //进数组界.
  176.             if(*_injson==‘[‘||*_injson==‘,’)
  177.             {
  178.                 *_outjson=*_injson;
  179.                 _injson++;
  180.                 _outjson++;
  181.                 if(!json_formatjsonkey(&_injson,injsonend,&_outjson,outjsonmax,addq,_split))
  182.                     return false;
  183.                 *injson=_injson;
  184.                 *outjson=_outjson;//指针因为函数的执行而向前跳越.
  185.             }
  186.             else if(*_injson==‘]’)
  187.             {
  188.                 //出界.进入父界.
  189.                 *_outjson=*_injson;
  190.                 _injson++;
  191.                 _outjson++;
  192.                 *injson=_injson;
  193.                 *outjson=_outjson;
  194.                 *_outjson=‘/0’;
  195.                 return true;//递归返回点.
  196.             }
  197.             else
  198.             {
  199.                 _injson++;
  200.             }
  201.             break;
  202.         case ‘{‘:
  203.             //进对象界.
  204.             if(*_injson==‘{‘||*_injson==‘,’)
  205.             {
  206.                 *_outjson=*_injson;
  207.                 _injson++;
  208.                 _outjson++;
  209.                 //进行KEY处理
  210.                 char *tmp=json_getcharaddr(_injson,injsonend,‘:’);
  211.                 if(tmp==NULL)return false;//没找到KEY的边界.
  212.                 char * keyfirst=json_getfirstcharaddr(_injson,tmp);
  213.                 char * keyend=json_getlastcharaddr(keyfirst,tmp);
  214.                 int tmplen=keyend-keyfirst;
  215.                 bool needq=*keyfirst!=‘”‘;
  216.                 if(addq)
  217.                 {
  218.                     if(needq)
  219.                     {
  220.                         *_outjson=‘/”‘;
  221.                         _outjson++;
  222.                     }
  223.                     memcpy(_outjson,keyfirst,tmplen);
  224.                     _outjson+=tmplen;
  225.                     _injson=tmp;
  226.                     if(needq)
  227.                     {
  228.                         *_outjson=‘/”‘;
  229.                         _outjson++;
  230.                     }
  231.                 }
  232.                 else
  233.                 {
  234.                     if(!needq)
  235.                     {
  236.                         keyfirst++;
  237.                         tmplen-=2;
  238.                     }
  239.                     memcpy(_outjson,keyfirst,tmplen);
  240.                     _outjson+=tmplen;
  241.                     _injson=tmp;
  242.                 }
  243.                 //进行值处理
  244.                 *_outjson=*_injson;
  245.                 _injson++;
  246.                 _outjson++;
  247.                 if(!json_formatjsonkey(&_injson,injsonend,&_outjson,outjsonmax,addq,_split))
  248.                     return false;
  249.                 *injson=_injson;
  250.                 *outjson=_outjson;//指针因为函数的执行而向前跳越.
  251.             }
  252.             else if(*_injson==‘}’)
  253.             {
  254.                 //出界.进入父界.
  255.                 *_outjson=*_injson;
  256.                 _injson++;
  257.                 _outjson++;
  258.                 *injson=_injson;
  259.                 *outjson=_outjson;
  260.                 *_outjson=‘/0’;
  261.                 return true;//递归返回点.
  262.             }
  263.             else
  264.             {
  265.                 _injson++;
  266.             }
  267.             break;
  268.         case ‘!’:
  269.             switch(split)
  270.             {//如果认定当前内容非ARRAY也非OBJ的话.以父内容来定界.
  271.             case ‘[‘:
  272.                 if(*_injson==‘]’||*_injson==‘,’)
  273.                 {
  274.                     //出界.进入父界.
  275.                     *_outjson=*_injson;
  276.                     *injson=_injson;
  277.                     *outjson=_outjson;
  278.                     return true;//递归返回点.
  279.                 }
  280.                 else
  281.                 {
  282.                     *_outjson=*_injson;
  283.                     _injson++;
  284.                     _outjson++;
  285.                     continue;
  286.                 }
  287.                 break;
  288.             case ‘{‘:
  289.                 if(*_injson==‘}’||*_injson==‘,’)
  290.                 {
  291.                     //出界.进入父界.
  292.                     *_outjson=*_injson;
  293.                     *injson=_injson;
  294.                     *outjson=_outjson;
  295.                     return true;//递归返回点.
  296.                 }
  297.                 else
  298.                 {
  299.                     *_outjson=*_injson;
  300.                     _injson++;
  301.                     _outjson++;
  302.                     continue;
  303.                 }
  304.                 break;
  305.             default:
  306.                 return false;
  307.             }
  308.             break;
  309.         default:
  310.             return false;
  311.         }
  312.     }
  313.     return false;
  314. }

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

关于xmsg

技术面前人人平等.同时技术也不分高低贵贱.正所谓学无大小,达者为尊.
此条目发表在C/C++分类目录,贴了, 标签。将固定链接加入收藏夹。