c++编撰json解析类

c++编写json解析类好久没有更新博客了,今天就将我之前写的一些代码陆续发上来。json.h#includeiostream#i

c++编写json解析类

      好久没有更新博客了,今天就将我之前写的一些代码陆续发上来。

json.h

#include<iostream>#include <string>using namespace std;class CJson{public:enum TYPE{STRING,LONG,ARRAY,OBJECT,BOOL,NAMEDOBG,STRINGA,LONGA,ARRAYA,OBJECTA,BOOLA,NAMEDOBGA};typedef struct _NODE{friend CJson;string m_key;TYPE type;string m_strVal;bool m_boolVal;long m_longVal;string m_objVal;_NODE(){memset(this,0,sizeof(_NODE));}_NODE* GetChild(){return m_child;}_NODE* GetNext(){return m_next;}_NODE* GetParent(){return m_parent;}_NODE* Get(int index){NODE* n=m_child;for(int i=0;i<index;i++){if(n==0){return 0;}n=n->m_next;}return n;}_NODE* Get(char* key){NODE* n=m_child;while(n){if(n->m_key==key){return n;}n=n->m_next;}return 0;}_NODE* Append(TYPE type,char* key,char* sVal,long nVal){NODE *node=new NODE;node->type=type;if(type==STRING){node->m_key=key;node->m_strVal=sVal;}else if (type==LONG){node->m_key=key;node->m_longVal=nVal;}else if(type==OBJECT){node->m_key=key;}else if (type==ARRAY){node->m_key=key;}else if(type==STRINGA){node->m_strVal=sVal;}else if (type==LONGA){node->m_longVal=nVal;}else if(type==OBJECTA){}else if (type==ARRAYA){}if(!m_child){m_child=node;node->m_parent=this;}else{NODE* n=m_child;while (n->m_next){n=n->m_next;}n->m_next=node;node->m_parent=this;}return node;}_NODE* Remove(_NODE* node)     //remove  child {if(!node){return 0;}NODE* nNext=node->m_next,*n=m_child;if(node==n){delete[] m_child;m_child=0;}else{while(n->m_next!=node){n=n->m_next;}n->m_next=node->m_next;delete node;}return nNext;}_NODE* Remove(int index)    //remove  array  child{if(index<0)return 0;NODE* n=m_child,*n1;if(index==0){NODE* n=m_child;m_child=m_child->m_next;delete n;return m_child;}for(int i=0;i<index;i++){n1=n;n=n->m_next;}n1->m_next=n->m_next;delete n;return n1->m_next;}_NODE* Remove(CJson* oCj)         //remove self{if(!oCj){return 0;}NODE* nNext=m_next;if(!m_parent){if(!oCj->m_root){return 0;}if(oCj->m_root==this){oCj->m_root=nNext;delete this;}else{NODE *n=oCj->m_root;while(n->m_next!=this){n=n->m_next;}NODE* n1=n->m_next;n->m_next=n1->m_next;delete n1;}}else{if(!m_parent->m_child){return 0;}if(m_parent->m_child==this){m_parent->m_child=nNext;delete this;}else{NODE *n=m_parent->m_child;while(n->m_next!=this){n=n->m_next;}NODE* n1=n->m_next;n->m_next=n1->m_next;delete n1;}}return nNext;}_NODE* Insert(_NODE* node,int index){if(!node){return 0;}if(!m_child){m_child=node;return node;}NODE* n=m_child;for(int i=0;i<index-1;i++){if(!n->m_next){break;}n=n->m_next;}node->m_next=n->m_next;n->m_next=node;node->m_parent=this;return node;}_NODE* Copy(){_NODE* n=new _NODE;*n=*this;n->m_child=0;n->m_parent=0;n->m_child=0;return n;}private:_NODE *m_child;_NODE *m_next;_NODE *m_parent;}NODE;CJson();~CJson();friend _NODE;bool Load(char*);NODE* GetRoot();string GetJsonString();NODE* Get(char*);NODE* Append(TYPE,char*,char*,long);NODE* Remove(NODE*);         //return next nodeNODE* Insert(NODE*,int);private:void Release(NODE*);void output(NODE *);inline string GetTab(int num){string tab;for(int i=0;i<num;i++){tab+="\t";}return tab;}char* m_str;NODE *m_root;string m_strOutput;};typedef CJson::NODE JsonNode;


json.cpp

#include "json.h"CJson::CJson(){m_str=0;m_root=0;}CJson::~CJson(){Release(m_root);if(m_str){delete[] m_str;m_str=0;}}void CJson::Release(NODE* node){if(node){Release(node->m_child);Release(node->m_next);delete node;}}JsonNode* CJson::GetRoot(){return m_root;}bool CJson::Load(char* str){NODE* CurNode;#define CHECKBLANK(ch) (ch==' ' || ch=='\t' || ch=='\r' || ch=='\n')if(str==0 || *str==0){return false;}m_str=new char[strlen(str)+1];strcpy(m_str,str);int i=0;while(m_str[i]!='{'){i++;}i++;NODE *m_par=0,*m_cur=0;bool bInKey=true;while(m_str[i]){if(!CHECKBLANK(m_str[i])){if(m_str[i]==','){bInKey=true;}else if(m_str[i]==':'){bInKey=false;}else if(m_str[i]=='['){if(!bInKey){m_cur->type=ARRAY;m_par=m_cur;bInKey=true;}else{NODE *node=new NODE;memset(node,0,sizeof(NODE));node->type=ARRAYA;node->m_parent=m_par;m_cur=node;if(m_par->m_child==0){m_par->m_child=node;}else{NODE *n=m_par->m_child;while(n->m_next){n=n->m_next;}n->m_next=node;}m_par=node;}}else if(m_str[i]==']'){if(m_par){m_par=m_par->m_parent;}bInKey=true;}else if(m_str[i]=='{'){if(!bInKey){m_cur->type=OBJECT;m_par=m_cur;bInKey=true;}else{NODE *node=new NODE;memset(node,0,sizeof(NODE));node->type=OBJECTA;node->m_parent=m_par;m_cur=node;if(m_par->m_child==0){m_par->m_child=node;}else{NODE *n=m_par->m_child;while(n->m_next){n=n->m_next;}n->m_next=node;}m_par=node;}}else if(m_str[i]=='}'){if(m_par){m_par=m_par->m_parent;}bInKey=true;}else if(m_str[i]=='\"'){if(!bInKey){i++;m_cur->type=STRING;while(m_str[i]!='\"' ||(m_str[i]=='\"' && m_str[i-1]=='\\')){m_cur->m_strVal+=m_str[i];i++;}while(m_str[i]!=','&& m_str[i]!=']' && m_str[i]!='}'){i++;}i--;}else{i++;NODE *node=new NODE;memset(node,0,sizeof(NODE));while(m_str[i]!='\"' ||(m_str[i]=='\"' && m_str[i-1]=='\\')){node->m_key+=m_str[i];i++;}if(m_par && (m_par->type==ARRAY || m_par->type==ARRAYA)){node->m_strVal=node->m_key;node->type=STRINGA;while(m_str[i]!=',' && m_str[i]!=']'){i++;}i--;}else{while(m_str[i]!=':'){i++;}i--;}if(m_root==0){m_root=node;m_cur=node;}else{m_cur=node;node->m_parent=m_par;if(m_par){if(m_par->m_child==0){m_par->m_child=node;}else{NODE *n=m_par->m_child;while(n->m_next){n=n->m_next;}n->m_next=node;}}else{NODE *n=m_root;while(n->m_next){n=n->m_next;}n->m_next=node;}}}}else if(m_str[i]>='1' && m_str[i]<='9'){if(m_par && (m_par->type==ARRAY || m_par->type==ARRAYA)){NODE *node=new NODE;memset(node,0,sizeof(NODE));node->type=LONGA;node->m_parent=m_par;m_cur=node;if(m_par->m_child==0){m_par->m_child=node;}else{NODE *n=m_par->m_child;while(n->m_next){n=n->m_next;}n->m_next=node;}if(m_str[i-1]=='-'){node->m_strVal+=m_str[i-1];}while(m_str[i]!=','&& m_str[i]!=']'){if(!CHECKBLANK(m_str[i])){node->m_strVal+=m_str[i];}node->m_longVal=atoi(node->m_strVal.data());i++;}i--;}else{m_cur->type=LONG;if(m_str[i-1]=='-'){m_cur->m_strVal+=m_str[i-1];}while(m_str[i]!=','&& m_str[i]!=']' && m_str[i]!='}'){if(!CHECKBLANK(m_str[i])){m_cur->m_strVal+=m_str[i];}m_cur->m_longVal=atoi(m_cur->m_strVal.data());i++;}i--;}}else if((m_str[i]>='a' && m_str[i]<='z') || (m_str[i]>='A' && m_str[i]<='Z')){if(m_par && (m_par->type==ARRAY || m_par->type==ARRAYA)){NODE *node=new NODE;memset(node,0,sizeof(NODE));node->m_parent=m_par;m_cur=node;if(m_par->m_child==0){m_par->m_child=node;}else{NODE *n=m_par->m_child;while(n->m_next){n=n->m_next;}n->m_next=node;}bool bInQ=false;while(bInQ ||(m_str[i]!=','&& m_str[i]!=']')){if(!CHECKBLANK(m_str[i])){if(m_str[i]=='\"' || m_str[i]=='\''){bInQ=!bInQ;}node->m_objVal+=m_str[i];}i++;}i--;if(m_cur->m_objVal=="true"  || m_cur->m_objVal=="false"){node->type=BOOLA;}else{node->type=NAMEDOBGA;}}else{bool bInQ=false;while(1){if(m_str[i]=='\"' || m_str[i]=='\''){bInQ=!bInQ;m_cur->m_objVal+=m_str[i];}else if(CHECKBLANK(m_str[i])){i++;continue;}else if(!bInQ && (m_str[i]==',' || m_str[i]==']' ||m_str[i]=='}')){i--;break;}else{m_cur->m_objVal+=m_str[i];}i++;}if(m_cur->m_objVal=="true"  || m_cur->m_objVal=="false"){m_cur->type=BOOL;}else{m_cur->type=NAMEDOBG;}}}}i++;}return true;}string CJson::GetJsonString(){m_strOutput="";output(m_root);m_strOutput="{\n"+m_strOutput+"\n}";return m_strOutput;}void CJson::output(NODE *n){static int nTab=1;if(n){if(n->m_parent){if(n!=n->m_parent->m_child){m_strOutput+=",\n";}}else{if(n!=m_root){m_strOutput+=",\n";}}if(n->type==ARRAY){m_strOutput=m_strOutput+GetTab(nTab)+"\""+n->m_key+"\":";m_strOutput+="\n"+GetTab(nTab)+"[\n";nTab++;output(n->m_child);nTab--;m_strOutput+="\n"+GetTab(nTab)+"]";}else if(n->type==OBJECT){m_strOutput=m_strOutput+GetTab(nTab)+"\""+n->m_key+"\":";m_strOutput+="\n"+GetTab(nTab)+"{\n";nTab++;output(n->m_child);nTab--;m_strOutput+="\n"+GetTab(nTab)+"}";}else if(n->type==OBJECTA){m_strOutput+=GetTab(nTab)+"{\n";nTab++;output(n->m_child);nTab--;m_strOutput+="\n"+GetTab(nTab)+"}";}else if(n->type==ARRAYA){m_strOutput+=GetTab(nTab)+"[\n";nTab++;output(n->m_child);nTab--;m_strOutput+="\n"+GetTab(nTab)+"]";}else if(n->type==STRINGA){m_strOutput+=GetTab(nTab)+"\""+n->m_strVal+"\"";}else if(n->type==LONGA){if(atoi(n->m_strVal.data())!=n->m_longVal){char str[100]={0};itoa(n->m_longVal,str,10);n->m_strVal=str;}m_strOutput+=GetTab(nTab)+n->m_strVal;}else if(n->type==LONG){char str[100]={0};itoa(n->m_longVal,str,10);n->m_strVal=str;m_strOutput=m_strOutput+GetTab(nTab)+"\""+n->m_key+"\":";m_strOutput=m_strOutput+n->m_strVal;}else if(n->type==STRING){m_strOutput=m_strOutput+GetTab(nTab)+"\""+n->m_key+"\":";m_strOutput=m_strOutput+"\""+n->m_strVal+"\"";}else if(n->type==BOOL || n->type==NAMEDOBG){m_strOutput=m_strOutput+GetTab(nTab)+"\""+n->m_key+"\":";m_strOutput=m_strOutput+n->m_objVal;}else if(n->type==BOOLA || n->type==NAMEDOBGA){m_strOutput+=GetTab(nTab)+n->m_objVal;}output(n->m_next);}}JsonNode* CJson::Get(char* key){if(m_root){NODE* n=m_root;while(n){if(n->m_key==key){return n;}n=n->m_next;}}return 0;}JsonNode* CJson::Append(TYPE type,char* key,char* sVal,long nVal){NODE *node=new NODE;node->type=type;if(type==STRING){node->m_key=key;node->m_strVal=sVal;}else if (type==LONG){node->m_key=key;node->m_longVal=nVal;}else if(type==OBJECT){node->m_key=key;}else if (type==ARRAY){node->m_key=key;}else if(type==STRINGA){node->m_strVal=sVal;}else if (type==LONGA){node->m_longVal=nVal;}else if(type==OBJECTA){}else if (type==ARRAYA){}if(!m_root){m_root=node;}else{NODE* n=m_root;while (n->m_next){n=n->m_next;}n->m_next=node;}return node;}JsonNode* CJson::Insert(NODE* node,int index){if(!node){return 0;}if(!m_root){m_root=node;return node;}NODE* n=m_root;for(int i=0;i<index-1;i++){if(!n->m_next){break;}n=n->m_next;}node->m_next=n->m_next;n->m_next=node;node->m_parent=0;return node;}JsonNode* CJson::Remove(NODE* node){if(!node){return 0;}NODE* nNext=node->m_next,*n=m_root;if(node==n){delete[] m_root;m_root=0;}else{while(n->m_next!=node){n=n->m_next;}n->m_next=node->m_next;delete node;}return nNext;}int main(){FILE *f=fopen("d:\\json.txt","rb");fseek(f,0,SEEK_END);long n=ftell(f);fseek(f,0,SEEK_SET);char *b=new char[n+1];b[n]=0;fread(b,1,n,f);fclose(f);CJson j;j.Load(b);//JsonNode* nn=j.Get("a")->Get(2)->Get(0);//JsonNode* nnn=nn->Copy();//j.Append(CJson::STRING,"qq","123",0);//j.Append(CJson::ARRAY,"qq1",0,0)->Append(CJson::ARRAYA,0,0,0)->Append(CJson::OBJECTA,0,0,0)->Append(CJson::STRING,"2","23",0);//nn->Remove(&j);//j.Get("a")->Insert(nnn,1);//j.Get("a")->Remove(0);cout<<j.GetJsonString()<<endl;delete[] b;}


        这个解析类的数据结构是二叉树,左子树是节点的兄弟节点的nextnode,右子树是节点的子节点的firstchild。

      文章不足之处还望大家多多指正。