返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >怎么用C++编写一个Json解析器
  • 783
分享到

怎么用C++编写一个Json解析器

2023-07-05 11:07:25 783人浏览 八月长安
摘要

今天小编给大家分享一下怎么用c++编写一个JSON解析器的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。之前用Rapidjso

今天小编给大家分享一下怎么用c++编写一个JSON解析器的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

之前用Rapidjson来做json的解析,但是,RapidJson还是有麻烦的地方,虽然速度非常快,但是由于用了非常多的优化技巧,反而无法做到我想要的那种简便的访问方式。

比如,有这么一个字符串

"{ \"a\":1000,\"b\":30000,\"c\":[123,456,789,5555, 1.0e2, true, false, null, \"test\", \"big big world\"]}"

我在C++里面需要非常简单的使用它,例如这样:

        static char text[] = "{ \"a\":1000,\"b\":30000,\"c\":[123,456,789,5555, 1.0e2, true, false, null, \"test\", \"big big world\"]}";        atom::CJson root = text;         root["a"] = 123;        root["c"] = true;        root["b"] = "b is the biggest";        atom::CJson test = "{\"new key\": 1037, 'test-key':1234e-5, 'array':[1,2,3,1,1,0] }";        root["e"] = test;        test["array"][0] = 1000;         atom::a_string value = root.Stringity();        printf( "%s\n", value.c_str() );

而输出结果如下:

{"a":123, "b":"b is the biggest", "c":1, "e":{"new key":1037, "test-key":0.012340, "array":[1000, 2, 3, 1, 1, 0, ], }, }

找了几个Json库,似乎都没有我想要的那种效果。快的访问很麻烦,访问方便点的速度又上不去。后来还是决定自己写一个。

自己写出来后,测试了一下,在不开优化的情况下,时间开销大概是RapidJson的8倍,如果开编译器优化,则时间开销是RapidJson的4倍左右。其实还是有可以再优化的地方,但再优化就必须要损失易用性为代价。想了一下,还是放弃了,这个解析速度和访问的方便程度我已经很满意了。

而且我自己写的Json还能支持序列化到流数据,如果采用这个方式,恢复的速度和RapidJson的解析差不多。

tokenizer数据结构的头文件和cpp文件

#ifndef TAGJSONTOKEN_H#define TAGJSONTOKEN_H//Begin section for file tagJsonToken.h//TODO: Add definitions that you want preserved//End section for file tagJsonToken.h#include "../stl/a_string.h"#include "../stl/allocator.h"#include "../tool/CVariablePtr.h"   namespace atom{        //@generated "UML to C++ (com.ibm.xtools.transfORM.uml2.cpp.CPPTransformation)"    struct tagJsonToken    {         //Begin section for atom::tagJsonToken        //TODO: Add attributes that you want preserved        //End section for atom::tagJsonToken         public:              //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            //typedef CVariablePtr<tagJsonToken>  Ptr ;               //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            typedef vector<tagJsonToken, atom_allocator<tagJsonToken> >  Array ;           public:              //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            U32 token;               //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            size_t start;               //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            size_t close;               //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            tagJsonToken();                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            tagJsonToken(const tagJsonToken & value);                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            tagJsonToken(U32 token);                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            tagJsonToken(U32 token, size_t start, size_t close);                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            ~tagJsonToken();                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            tagJsonToken & operator=(const tagJsonToken & value);        };  //end struct tagJsonToken   } //end namespace nova   #endif
#include "tagJsonToken.h"//Begin section for file tagJsonToken.cpp//TODO: Add definitions that you want preserved//End section for file tagJsonToken.cpp  //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::tagJsonToken::tagJsonToken() : token(0),start(0),close(0){    //TODO Auto-generated method stub} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::tagJsonToken::tagJsonToken(const tagJsonToken & in) : token(in.token),start(in.start),close(in.close){    //TODO Auto-generated method stub} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::tagJsonToken::tagJsonToken(U32 t) : token(t),start(0),close(0){    //TODO Auto-generated method stub} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::tagJsonToken::tagJsonToken(U32 t, size_t s, size_t c) : token(t),start(s),close(c){    //TODO Auto-generated method stub} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::tagJsonToken::~tagJsonToken() {    //TODO Auto-generated method stub} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::tagJsonToken & atom::tagJsonToken::operator=(const tagJsonToken & in) {    //TODO Auto-generated method stub    token = in.token;    start = in.start;    close = in.close;    return( * this );}

json节点的头文件和cpp文件

#ifndef TAGJSONKEYVALUE_H#define TAGJSONKEYVALUE_H//Begin section for file tagJsonKeyValue.h//TODO: Add definitions that you want preserved//End section for file tagJsonKeyValue.h#include "../stl/a_string.h"#include "../stl/stl_extend.h"#include "../variant/CVariant.h"#include "../tool/CVariablePtr.h"   namespace atom{       //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"    struct tagJsonKeyValue    {         //Begin section for atom::tagJsonKeyValue        //TODO: Add attributes that you want preserved        //End section for atom::tagJsonKeyValue         public:              //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            typedef CVariablePtr<tagJsonKeyValue>  Ptr ;              //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            typedef vector<pair<size_t, tagJsonKeyValue::Ptr>, atom_allocator<pair<size_t, tagJsonKeyValue::Ptr> > >  Array ;            public:              //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            a_string index;               //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            CVariant value;               //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            Array group;               //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            //Map query;               //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            tagJsonKeyValue();                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            tagJsonKeyValue(const char * value);                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            tagJsonKeyValue(const CVariant & data);                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            tagJsonKeyValue(const char * value, const CVariant & data);                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            tagJsonKeyValue(const tagJsonKeyValue & value);                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            ~tagJsonKeyValue();                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            tagJsonKeyValue & operator=(const tagJsonKeyValue & value);        };  //end struct tagJsonKeyValue   } //end namespace atom   template<class ArcHive>inline void Serialize(Archive & archive, atom::tagJsonKeyValue & value, bool isSave){    UNREFERENCED_PARAMETER( isSave );    archive.Bind( value.index );    archive.Bind( value.value );    archive.Bind( value.group );}   #endif
#include "tagJsonKeyValue.h"//Begin section for file tagJsonKeyValue.cpp//TODO: Add definitions that you want preserved//End section for file tagJsonKeyValue.cpp  //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::tagJsonKeyValue::tagJsonKeyValue() {    //TODO Auto-generated method stub} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::tagJsonKeyValue::tagJsonKeyValue(const char * in):index(in ? in : ""){    //TODO Auto-generated method stub} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::tagJsonKeyValue::tagJsonKeyValue(const CVariant & in) :value(in){    //TODO Auto-generated method stub} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::tagJsonKeyValue::tagJsonKeyValue(const char * in_1, const CVariant & in_2) :index(in_1 ? in_1 : ""),value(in_2){    //TODO Auto-generated method stub} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::tagJsonKeyValue::tagJsonKeyValue(const tagJsonKeyValue & in) :index(in.index),value(in.value),group(in.group){    //TODO Auto-generated method stub} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::tagJsonKeyValue::~tagJsonKeyValue() {    //TODO Auto-generated method stub} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::tagJsonKeyValue & atom::tagJsonKeyValue::operator=(const tagJsonKeyValue & in) {    //TODO Auto-generated method stub    index = in.index;    value = in.value;    group = in.group;    return( * this );}

接下来是 Tokenizer 的实现

#include "CJsonTokenizer.h"#include "../../enumeration/JSON_TOKEN.h"//Begin section for file CJsonTokenizer.cpp//TODO: Add definitions that you want preserved//End section for file CJsonTokenizer.cpp   //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::CJsonTokenizer::CJsonTokenizer() {    //TODO Auto-generated method stub    tokens.reserve( 1024 );} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::CJsonTokenizer::~CJsonTokenizer() {    //TODO Auto-generated method stub} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"bool atom::CJsonTokenizer::Start(const char * json) {    //TODO Auto-generated method stub    if( json == NULL ) {        return false;    }     size_t offset = 0;    size_t length = strlen( json );     buffer.Alloc( length );    if( buffer ) {        buffer.Store( json, length );    }     bool result = true;    for( ;; )    {        // skip any reserved or space characters.        for( ; IsSpace(json, offset, length); ++ offset );         // offset check        if( offset >= length )        {            tokens.push_back( tagJsonToken() );            tokens.back().token = JT_END;            break;        }         char c = json[offset];         // create token        if( IsNull(json, offset, length) )        {            offset += 4;            tokens.push_back( tagJsonToken(JT_NULL) );        }        else        if( c == ',' )        {            offset += 1;            tokens.push_back( tagJsonToken(JT_COMMA) );        }        else        if( c == ':' )        {            offset += 1;            tokens.push_back( tagJsonToken(JT_COLON) );        }        else        if( c == '{' )        {            offset += 1;            tokens.push_back( tagJsonToken(JT_OBJECT_BEGIN) );        }        else        if( c == '[' )        {            offset += 1;            tokens.push_back( tagJsonToken(JT_ARRAY_BEGIN) );        }        else        if( c == ']' )        {            offset += 1;            tokens.push_back( tagJsonToken(JT_ARRAY_CLOSE) );        }        else        if( c == '}' )        {            offset += 1;            tokens.push_back( tagJsonToken(JT_OBJECT_CLOSE) );        }        else        if( IsTrue(json, offset, length) )        {            offset += 4;            tokens.push_back( tagJsonToken(JT_BOOL, 1, 0) );        }        else        if( IsFalse(json, offset, length) )        {            offset += 5;            tokens.push_back( tagJsonToken(JT_BOOL) );        }        else        if( c == '\'' || c == '\"' )        {            // read string will modify the offset;            size_t start(0), close(0);            ReadString( json, offset, length, start, close );             if( start == 0 || close == 0 || close <= start )             {                char msg[32];                sprintf( msg, "%zu", offset );                 errmsg = "Failed read string from offset ";                errmsg = errmsg + msg;                 tokens.clear();                result = false;                break;            }             tokens.push_back( tagJsonToken(JT_STRING, start, close) );        }        else        if( IsNumber(json, offset, length) )        {            size_t start(0), close(0);            ReadNumber( json, offset, length, start, close );             // read number will modify the offset;            if( start == 0 || close == 0 || close <= start )             {                char msg[32];                sprintf( msg, "%zu", offset );                 errmsg = "Failed read number from offset ";                errmsg = errmsg + msg;                 tokens.clear();                result = false;                break;            }             tokens.push_back( tagJsonToken(JT_NUMBER, start, close) );        }        else        {            char msg[32];            sprintf( msg, "%zu", offset );             errmsg = "Invalid char at offset ";            errmsg = errmsg + msg;             tokens.clear();            result = false;            break;        }    }    return result;} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"bool atom::CJsonTokenizer::IsNull(const char * json, size_t & offset, size_t length) {    //TODO Auto-generated method stub    bool result = false;    if( json )    {        // length must enough.        if( (length - offset) + 1 >= 4 )        {            const char * site = json + offset;            if( *site == 'n' || *site == 'N' )            {                ++ site;                if( *site == 'u' || *site == 'U' )                {                    ++ site;                    if( *site == 'l' || *site == 'L' )                    {                        ++ site;                        if( *site == 'l' || *site == 'L' )                        {                            result = true;                        }                    }                }            }        }    }    return result;} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"bool atom::CJsonTokenizer::IsTrue(const char * json, size_t & offset, size_t length) {    //TODO Auto-generated method stub    bool result = false;    if( json )    {        // length must enough.        if( (length - offset) + 1 >= 4 )        {            const char * site = json + offset;            if( *site == 't' || *site == 'T' )            {                ++ site;                if( *site == 'r' || *site == 'R' )                {                    ++ site;                    if( *site == 'u' || *site == 'U' )                    {                        ++ site;                        if( *site == 'e' || *site == 'E' )                        {                            result = true;                        }                    }                }            }        }    }    return result;} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"bool atom::CJsonTokenizer::IsFalse(const char * json, size_t & offset, size_t length) {    //TODO Auto-generated method stub    bool result = false;    if( json )    {        // length must enough.        if( (length - offset) + 1 >= 5 )        {            const char * site = json + offset;            if( *site == 'f' || *site == 'F' )            {                ++ site;                if( *site == 'a' || *site == 'A' )                {                    ++ site;                    if( *site == 'l' || *site == 'L' )                    {                        ++ site;                        if( *site == 's' || *site == 'S' )                        {                            ++ site;                            if( *site == 'e' || *site == 'E' )                            {                                result = true;                            }                        }                    }                }            }        }    }    return result;} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"bool atom::CJsonTokenizer::IsSpace(const char * json, size_t & offset, size_t length) {    //TODO Auto-generated method stub    if( !json ) {        return false;    }     bool result = false;    if( offset < length )    {        if( json[offset] <= 0x20 )        {            result = true;        }    }    return result;} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"bool atom::CJsonTokenizer::IsNumber(const char * json, size_t & offset, size_t length) {    //TODO Auto-generated method stub    if( !json ) {        return false;    }     bool result = false;    if( offset < length )    {        char c = json[offset];        result = IsDigit( c ) || c == '-';    }    return result;} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"bool atom::CJsonTokenizer::IsEscape(const char * json, size_t & offset, size_t length) {    //TODO Auto-generated method stub    if( !json ) {        return false;    }     bool result = false;    if( offset < length )    {        char c = json[offset];        if( c == '\"' || c == '\\' || c == '/' ||            c == 'b'  || c == 'f'  || c == 'n' ||            c == 't'  || c == 'r'  || c == 'u' )        {            result = true;        }    }    return result;} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"bool atom::CJsonTokenizer::ReadNumber(const char * json, size_t & offset, size_t length, size_t & start, size_t & close) {    //TODO Auto-generated method stub    if( !json ) {        return false;    }     if( offset >= length ) {        return false;    }     size_t backup = offset;     start = offset;    close = offset;     if( json[offset] == '-' )     {        ++ close; ++ offset;    }      char c = 0;    bool succeed = true;     // read integer part        size_t bias(0); bool stop(false);    for( ;; ++ bias )     {        if( offset == length ) {            break;        }         if( offset  > length ) {            succeed = false;            break;        }         c = json[offset];         // stop flag        if( stop == true ) {            break;        }         // if 0 is the first digit.        if( bias == 0 && c == '0' )        {            ++ close; ++ offset;            stop = true;            continue;        }         if( IsDigit(c) )        {            ++ close; ++ offset;            continue;        }         // The first char is illegal, set failed.        if( bias == 0 ) {            succeed = false;        }         // if c is not digit, break;        break;    }     if( succeed &&         offset == length ) {        return true;    }     // read frac part    if( succeed && c == '.' )    {        ++ close; ++ offset;         bias = 0;        for( ;; ++ bias )         {            if( offset == length ) {                break;            }             if( offset  > length ) {                succeed = false;                break;            }             c = json[offset];             if( IsDigit(c) )            {                ++ close; ++ offset;                continue;            }             if( bias == 0 ) {                succeed = false;            }             // if c is not digit, break;            break;        }    }     if( succeed &&         offset == length ) {        return true;    }     // read exp part    if( succeed && (        c == 'e' || c == 'E' ) )    {        ++ close; ++ offset;         bias = 0;        for( ;; ++ bias )         {            if( offset == length ) {                break;            }             if( offset  > length ) {                succeed = false;                break;            }             c = json[offset];             if( c == '-' )            {                if( bias == 0 )                {                    ++ close; ++ offset;                    continue;                }                else                {                    succeed = false;                    break;                }            }             if( IsDigit(c) )            {                ++ close; ++ offset;                continue;            }             if( bias == 0 ) {                succeed = false;            }             // if c is not digit, break;            break;        }    }     if( succeed == false ) {        offset = backup; start = close = 0;    }    return succeed;} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"bool atom::CJsonTokenizer::ReadString(const char * json, size_t & offset, size_t length, size_t & start, size_t & close) {    //TODO Auto-generated method stub    if( !json ) {        return false;    }     if( offset >= length ) {        return false;    } size_t backup = offset; char quotation = 0;if (json[offset] == '\"' || json[offset] == '\'') {        quotation = json[offset ++];}     start = close = offset;     char c;    bool succeed = true;  for( ;; ){        // check the offset.        if( offset >= length )         {            succeed = false;            break;        } c = json[offset ++]; // is escpae ? if( c == '\\' ){if( !IsEscape(json, offset, length) ){                succeed = false;break;} ++ close;             // because the IsEscape function already verified the             // offset range. so, here's offset is valid.c = json[offset ++]; ++ close;             // Process Unicode,from \u0000 to \uffffif( c == 'u' )             {                 // memory border check                if( length - offset + 1 < 4 ) {                    succeed = false;                    break;                } for( size_t i = 0; i < 4; ++ i )                 {c = json[offset ++]; if( IsHex(c) )                     {++ close;}else                     {succeed = false;                        break;}}                 // if failed to process Unicode, stop the main loop.                if( !succeed ) break;}}         // another quotation ? else         if( c == quotation )        { break;}else         if( c == '\r' || c == '\n')         {            succeed = false;            break;}else         {++ close;}}     // 如果失败,则清理现场    if( succeed == false ) {    offset = backup; start = close = 0;    }     return succeed;} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::tagJsonToken::Array & atom::CJsonTokenizer::GetTokens() {    //TODO Auto-generated method stub    return tokens;} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::a_string atom::CJsonTokenizer::GetError() {    //TODO Auto-generated method stub    return errmsg;} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"const char * atom::CJsonTokenizer::GetString(size_t start, size_t close){    //TODO Auto-generated method stub    static char text[] = "";    size_t length = buffer.GetLength();    if( start < length && close < length && close > start )     {        buffer.Query<char>()[close] = 0;        return & buffer.Query<char>()[start];    }    return text;}

Parser的实现:

#include "CJsonParser.h"#include "CJsonTokenizer.h"#include "../stl/string_splite.h"#include "../../enumeration/JSON_TOKEN.h"//Begin section for file CJsonParser.cpp//TODO: Add definitions that you want preserved//End section for file CJsonParser.cpp  //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::CJsonParser::CJsonParser() {    //TODO Auto-generated method stub} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::CJsonParser::~CJsonParser() {    //TODO Auto-generated method stub} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"bool atom::CJsonParser::Parse(const char * text, CJson & json) {    //TODO Auto-generated method stub    if( text == NULL ) {        error = "Invalid arguments";        return false;    }     bool result = false;    CJsonTokenizer tokenizer;        if( tokenizer.Start(text) == false ) {        error = tokenizer.GetError();        return false;    }     if( tokenizer.GetTokens().empty() ) {        error = "Empty json string";        return false;    }     size_t offset   = 0;    U32 begin_token = tokenizer.GetTokens().front().token;    if( begin_token == JT_ARRAY_BEGIN  )    {        result = ParseArray  ( tokenizer, offset, json );    }    else    if( begin_token == JT_OBJECT_BEGIN )    {        result = ParseObject ( tokenizer, offset, json );    }    else    if( IsPrimary(begin_token) )    {        CVariant data;        result = ParsePrimary( tokenizer, offset, data );         if( result )         {            // 一开始就是原型的字符串必须立即结束            if( tokenizer.GetTokens().size() <= offset ||                 tokenizer.GetTokens().at(offset).token == JT_END )            {                json = data;            }            else            {                error  = "Json should ended after the 1st element";                 result = false;            }        }    }    return result;} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::a_string atom::CJsonParser::GetError() {    //TODO Auto-generated method stub    return error;} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"bool atom::CJsonParser::IsPrimary(U32 type) {    //TODO Auto-generated method stub    return         type == JT_BOOL   || type == JT_NULL ||         type == JT_NUMBER || type == JT_STRING;} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"bool atom::CJsonParser::ParseArray(CJsonTokenizer & tokenizer, size_t & offset, CJson & node) {    //TODO Auto-generated method stub    tagJsonToken::Array & tokens = tokenizer.GetTokens();    if( offset >= tokens.size() ) {        error = "Invalid offset";        return false;    }     if( tokens[offset].token != JT_ARRAY_BEGIN ) {        error = "Invalid array token";        return false;    }     size_t backup = offset;     // consume [    ++ offset;     bool result = true;    for( ;; )    {        if( offset >= tokens.size() )         {            error  = "Tokens not complete";             result = false;            break;        }         if( tokens[offset].token == JT_ARRAY_CLOSE )        {            ++ offset;  // consume ]            break;        }         if( tokens[offset].token == JT_ARRAY_BEGIN  )        {            CJson data;            if( false ==                 ParseArray(tokenizer, offset, data) )             {                result = false;                break;            }             node.Push( data );        }        else        if( tokens[offset].token == JT_OBJECT_BEGIN )        {            CJson data;            if( false ==                 ParseObject(tokenizer, offset, data) )             {                result = false;                break;            }             node.Push( data );        }        else        if( tokens[offset].token == JT_COMMA )        {            ++ offset;        }        else         if( IsPrimary(tokens[offset].token) )        {            CVariant data;            if( false ==                 ParsePrimary(tokenizer, offset, data) )             {                result = false;                break;            }             node.Push( data );        }        else        {            error  = "Invalid token in array";            result = false;            break;        }    }     if( result == false ) {        offset = backup;    }    return result;} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"bool atom::CJsonParser::ParseObject(CJsonTokenizer & tokenizer, size_t & offset, CJson & node) {    //TODO Auto-generated method stub    tagJsonToken::Array & tokens = tokenizer.GetTokens();    if( offset >= tokens.size() ) {        error = "Invalid offset";        return false;    }     if( tokens[offset].token != JT_OBJECT_BEGIN )     {        error = "Invalid object token";        return false;    }     size_t backup = offset;     // consume {    ++ offset;     bool result = true;    for( ;; )    {        if( offset >= tokens.size() )         {            error  = "Tokens not complete";             result = false;            break;        }         if( tokens[offset].token == JT_OBJECT_CLOSE )        {            ++ offset;  // consume }            break;        }         if( tokens[offset].token == JT_COMMA )        {            ++ offset;  // consume ,            continue;        }         // 读key,key必须是string类型        if( tokens[offset].token != JT_STRING )        {            error  = "Invalid key token type";            result = false;            break;        }         // 创建对象的键值对。        CJson value = node[            tokenizer.GetString(            tokens[offset].start,             tokens[offset].close)];         ++ offset;         if( offset >= tokens.size() )         {            error  = "Tokens not complete";             result = false;            break;        }         if( tokens[offset].token != JT_COLON )        {            error  = "Invalid splite token type";            result = false;            break;        }         ++ offset;  // consume :         if( offset >= tokens.size() )         {            error  = "Tokens not complete";             result = false;            break;        }         if( IsPrimary(tokens[offset].token) )        {            CVariant data;            if( false ==                 ParsePrimary(tokenizer, offset, data) )             {                result = false;                break;            }             value = data;        }        else        if( tokens[offset].token == JT_ARRAY_BEGIN  )        {            CJson data;            if( false ==                 ParseArray(tokenizer, offset, data) )             {                result = false;                break;            }             value = data;        }        else        if( tokens[offset].token == JT_OBJECT_BEGIN )        {            CJson data;            if( false ==                 ParseObject(tokenizer, offset, data) )             {                result = false;                break;            }             value = data;        }        else         {            error  = "Invalid value token type";            result = false;            break;        }    }     if( result == false ) {        offset = backup;    }    return result;} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"bool atom::CJsonParser::ParsePrimary(CJsonTokenizer & tokenizer, size_t & offset, CVariant & data) {    //TODO Auto-generated method stub    tagJsonToken::Array & tokens = tokenizer.GetTokens();    if( offset >= tokens.size() ) {        error = "Invalid offset";        return false;    }     bool result = true;    switch( tokens[offset].token )    {    case JT_NUMBER:        {            const char * value = tokenizer.GetString(                 tokens[offset].start,                 tokens[offset].close );             size_t length = strlen( value );            size_t splite = 0;            for( size_t i = 0; i < length; ++ i )            {                if( value[i] == 'e' || value[i] == 'E' ) {                    splite = i;                }            }             // only one part.            if( length > 0 )            {                // 先计算指数                char * stop = NULL;                 I64 exp = 0;                if( splite != 0 )                {                    #if defined(_WIN32)                    exp = static_cast<I64>( _strtoi64( & value[splite + 1], & stop, 10 ) );                    #else                    exp = static_cast<I64>(  strtoll ( & value[splite + 1], & stop, 10 ) );                    #endif                }                 if( splite == 0 )                {                    splite = length;                }                 bool is_float = false;                for( size_t i = 0; i < splite; ++ i )                {                    if( value[i] == '.' ) {                        is_float = true;                    }                }                 // 再判断前面部分                if( is_float == false )                {                    #if defined(_WIN32)                    I64 integer = static_cast<I64>( _strtoi64( value, & stop, 10 ) );                    #else                    I64 integer = static_cast<I64>(  strtoll ( value, & stop, 10 ) );                    #endif                     double range = integer * pow( 10, exp );                     abs( range - static_cast<I64>(range) ) < 1e-6 ?                        data = static_cast<I64>(range):                        data = range;                     ++ offset;                }                else                {                    double decimal = strtod( value, & stop );                    double range = decimal * pow( 10, exp );                                        abs( range - static_cast<I64>(range) ) < 1e-6 ?                        data = static_cast<I64>(range):                        data = range;                     ++ offset;                }            }            else             {                error  = "Invalid number format";                result = false;            }        }        break;    case JT_STRING:        {            data = tokenizer.GetString(                 tokens[offset].start,                 tokens[offset].close );            ++ offset;        }        break;    case JT_NULL:        {            data.Clear(); ++ offset;        }        break;    case JT_BOOL:        {            bool value = tokens[offset ++].start == 1;            data = value;        }        break;    default:        error = "Not primary"; result = false;        break;    }    return result;}

最后的重点:CJson 类的实现:

#ifndef CJSON_H#define CJSON_H//Begin section for file CJson.h//TODO: Add definitions that you want preserved//End section for file CJson.h#include "tagJsonKeyValue.h"#include "../variant/CVariant.h"   namespace atom{       //<p>This class is not thread safe. Should used under critical section's protection.</p>    //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"    class CJson    {         //Begin section for atom::CJson        //TODO: Add attributes that you want preserved        //End section for atom::CJson         private:              //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            mutable tagJsonKeyValue::Ptr root;               //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            mutable U08 type;               //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            U08 CheckType(const tagJsonKeyValue::Ptr & node);                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            bool Assign(U08 in_type, const tagJsonKeyValue::Ptr & in, bool & deep);            public:             //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            CJson();                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            CJson(const CJson & value);                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            CJson(const tagJsonKeyValue::Ptr & value);                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            CJson(const char * value);                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            operator CVariant() const;                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            CJson & operator=(const CJson & value);                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            CJson & operator=(const CVariant & value);                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            CJson & operator=(const tagJsonKeyValue::Ptr & value);                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            CJson & operator=(const char * value);                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            CJson operator[](I32 offset);                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            CJson operator[](size_t offset);                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            CJson operator[](const char * index);                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            size_t Length();                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            U08 GetType();                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            bool Push(const CVariant & data);                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            bool Push(const CJson & data);                //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            a_string Stringity();               //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            a_string Stringity(const tagJsonKeyValue::Ptr & value);               //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            CJson Clone();               //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"            tagJsonKeyValue Clone(const tagJsonKeyValue::Ptr & value);               template<class A>            inline void Serialize(A & ar, bool save)            {            ar.Bind( type );            ar.Bind( root );            }       };  //end class CJson   } //end namespace atom   #endif
#include "CJson.h"#include "CJsonParser.h"#include "../stl/stl_extend.h"#include "../../enumeration/JSON_VALUE_TYPE.h"#include "../../enumeration/VARIANT_TYPE.h"//Begin section for file CJson.cpp//TODO: Add definitions that you want preserved//End section for file CJson.cpp  //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::CJson::CJson() :type(JVT_NONE){    //TODO Auto-generated method stub} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::CJson::CJson(const CJson & value) :root(value.root),type(value.type){    //TODO Auto-generated method stub} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::CJson::CJson(const tagJsonKeyValue::Ptr & value) :type(JVT_NONE){    //TODO Auto-generated method stub    * this = value;} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::CJson::CJson(const char * value) :type(JVT_NONE){    //TODO Auto-generated method stub    * this = value;} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"bool atom::CJson::Assign(U08 in_type, const tagJsonKeyValue::Ptr & in, bool & deep){    //TODO Auto-generated method stub    if( root == NULL ) {        root = tagJsonKeyValue();    }     if( root == NULL ) {        return false;    }     // 对不同的类型有不同的设置方式;    // 此处是深度复制,是否需要浅层复制?    deep = true;    switch( type )    {    case JVT_OBJECT:    case JVT_ARRAY:        root -> group.clear();    case JVT_NONE:    case JVT_PRIMARY:        root -> value.Clear();        root -> index = in -> index;        root -> value = in -> value;        root -> group = in -> group;        type = in_type;        break;    case JVT_PAIR:        switch( in_type )        {        case JVT_NONE:        case JVT_PRIMARY:            root -> value.Clear();            if( in ) {                root -> value = in -> value;                type = JVT_PRIMARY;            }            break;        case JVT_OBJECT:            type = JVT_OBJECT;            root -> group.clear();            if( in ) {                root -> group = in -> group;            }            break;        case JVT_ARRAY:            type = JVT_ARRAY;            root -> group.clear();            if( in ) {                root -> group = in -> group;            }            break;        case JVT_PAIR:            type = JVT_OBJECT;            root -> value.Clear();            root -> group.clear();             if( in )            {                atom_hash<const char *> hasher;                root -> group.push_back( make_pair(                    hasher( in -> index.c_str() ), in) );                 // 唯有插入pair变成object时,才是浅层复制                deep = false;            }        }        break;    }    return true;} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::CJson & atom::CJson::operator=(const CJson & in) {    //TODO Auto-generated method stub    bool deep = false;    if( Assign(in.type, in.root, deep) )    {        if( deep )        {            in.root -> index = root -> index;            in.root -> value = root -> value;            in.root -> group = root -> group;            in.type = type;        }    }    return( * this );} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::CJson & atom::CJson::operator=(const tagJsonKeyValue::Ptr & in) {    //TODO Auto-generated method stub    // 该函数直接赋值,因为这个函数仅仅是在Parse时调用    root = in;    type = CheckType( in );    return( * this );} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::CJson & atom::CJson::operator=(const CVariant & value){    //TODO Auto-generated method stub    // 如果为空,则赋予初值    if( root == NULL ) {        root = tagJsonKeyValue();    }     if( root == NULL ) {        return( * this );    }     // 对不同的类型有不同的设置方式;    switch( type )    {    case JVT_OBJECT:    case JVT_ARRAY:        root -> group.clear();     case JVT_NONE:    case JVT_PRIMARY:        root -> value = value;        type = JVT_PRIMARY;        break;    case JVT_PAIR:        root -> value = value;        break;    }    return( * this );} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::CJson & atom::CJson::operator=(const char * value){    //TODO Auto-generated method stub    if( value )    {        CJsonParser parser; CJson node;        if( parser.Parse(value, node) ) {            * this = node;        } else {            * this = CVariant( value );        }    }    return( * this );} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::CJson atom::CJson::operator[](I32 offset) {    //TODO Auto-generated method stub    return this -> operator[]( static_cast<size_t>(offset) );} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::CJson atom::CJson::operator[](size_t offset) {    //TODO Auto-generated method stub    if( root && type == JVT_ARRAY )    {        if( offset < root -> group.size() )        {            return CJson( root -> group[offset].second );        }    }    return CJson();} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::CJson atom::CJson::operator[](const char * index) {    //TODO Auto-generated method stub    // 访问类成员,本身不能是数组,也就是说root的大小必须为1    // 然后这个index必须存在。    if( !index ) {        return CJson();    }     // 如果为空,则初始化一个    if( root == NULL ) {        root = tagJsonKeyValue();        root -> group.reserve( 32 );    }     if( root == NULL ) {        return CJson();    }     // 任何类型,都强制转换为object,然后重新设置    switch( type )    {    case JVT_ARRAY:        root -> group.clear();    case JVT_PAIR:        root -> index.clear();    case JVT_PRIMARY:        root -> value.Clear();    case JVT_NONE:        type = JVT_OBJECT;        break;    case JVT_OBJECT:        break;    }     atom_hash<const char *> hasher;    size_t key = hasher( index );     bool finded = false;    for( tagJsonKeyValue::Array::iterator        it  = root -> group.begin();        it != root -> group.end(); ++ it )    {        if( it -> first != key ) {            continue;        }         // 必须判断 it second 内是否有值        if( it -> second != NULL )        {            finded = true;            return CJson( it -> second );        }    }     if( finded == false )    {        root -> group.push_back(            make_pair( key, tagJsonKeyValue(index) ) );         // return directly        return CJson( root -> group.back().second );    }    return CJson();} namespace atom{       //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"    CJson::operator CVariant() const    {        //TODO Auto-generated method stub        if( root &&             type == JVT_PRIMARY ||             type == JVT_PAIR )         {            return CVariant( root -> value );        }        return CVariant();    }   }//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"U08 atom::CJson::CheckType(const tagJsonKeyValue::Ptr & node){    //TODO Auto-generated method stub    U08 result = JVT_NONE;    if( node )    {        if( node -> group.empty() == false )        {            node -> group.front().first == 0 ?                 result = JVT_ARRAY :                 result = JVT_OBJECT;        }        else        if( node -> index.empty() == false )        {            result = JVT_PAIR;        }        else        {            result = JVT_PRIMARY;        }    }    return result;} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"size_t atom::CJson::Length() {    //TODO Auto-generated method stub    size_t result = 0;    if( root &&        type == JVT_ARRAY ) {        result = root -> group.size();    }    return result;} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"U08 atom::CJson::GetType(){    //TODO Auto-generated method stub    return type;} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"bool atom::CJson::Push(const CVariant & data) {    //TODO Auto-generated method stub    bool result = false;        if( root == NULL ) {        root = tagJsonKeyValue();        root -> group.reserve( 32 );    }     if( root == NULL ) {        return false;    }     result = true;     switch( type )    {    case JVT_NONE:        root -> group.push_back(             make_pair( 0, tagJsonKeyValue(data) ) );        type = JVT_ARRAY;        break;    case JVT_PRIMARY:        if( root -> value.Type() != VT_UNKNOW )        {            // 先把自己的值插进去            root -> group.push_back(                 make_pair( 0, tagJsonKeyValue(root -> value) ) );            root -> value.Clear();             root -> group.push_back(                 make_pair( 0, tagJsonKeyValue(data) ) );            type = JVT_ARRAY;        }        break;    case JVT_PAIR:        // 将pair的值变成数组        root -> group.push_back(             make_pair( 0, tagJsonKeyValue(root -> value) ) );        root -> value.Clear();         root -> group.push_back(             make_pair( 0, tagJsonKeyValue(data) ) );        type = JVT_ARRAY;        break;    case JVT_OBJECT:        {            // 将object的变成数组的第一个元素            tagJsonKeyValue value;            value.group = root -> group;             // 清理掉原有的数据,再插入到数组中            root -> group.clear();            root -> group.push_back( make_pair(0, value) );             value.group.clear();            value.value = data;             root -> group.push_back( make_pair(0, value) );            type = JVT_ARRAY;        }        break;    case JVT_ARRAY:        root -> group.push_back( make_pair(0, tagJsonKeyValue(data) ) );        break;    default:        result = false;        break;    }     return result;} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"bool atom::CJson::Push(const CJson & data) {    //TODO Auto-generated method stub    bool result = false;     if( root == NULL ) {        root = tagJsonKeyValue();        root -> group.reserve( 32 );    }     if( root == NULL ) {        return false;    }     if( data.root == NULL ) {        return false;    }     // push a pair into array is not allowd    if( data.root -> index.empty() == false ) {        return false;    }     result = true;    switch( type )    {    case JVT_NONE:        {            root -> group.push_back( make_pair(0, data.root) );            type = JVT_ARRAY;        }        break;    case JVT_PRIMARY:        if( root -> value.Type() != VT_UNKNOW )        {            // push back self value first            root -> group.push_back(                 make_pair( 0, tagJsonKeyValue(root -> value) ) );            root -> value.Clear();             // push json object's value            root -> group.push_back(                 make_pair(0, data.root) );            type = JVT_ARRAY;        }        break;    case JVT_PAIR:        {            // convert pair's value as a array's element            root -> group.push_back(                make_pair( 0, tagJsonKeyValue(root -> value) ) );            root -> value.Clear();             root -> group.push_back(                 make_pair( 0, data.root ) );            type = JVT_ARRAY;        }        break;    case JVT_OBJECT:        {            // push objct into array.            tagJsonKeyValue value;            value.group = root -> group;             root -> group.clear();            root -> group.push_back( make_pair(0, value) );            root -> group.push_back( make_pair(0, data.root) );            type = JVT_ARRAY;        }        break;    case JVT_ARRAY:        {            root -> group.push_back( make_pair(0, data.root) );        }        break;    default:        result = false;        break;    }    return result;} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::a_string atom::CJson::Stringity(){    return Stringity( root );} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::a_string atom::CJson::Stringity(const tagJsonKeyValue::Ptr & value){    a_string result;    if( value )    {        U08 genre = CheckType( value );        switch( genre )        {        case JVT_NONE:            result += "null";            break;        case JVT_PAIR:            result += "\"";            result += value -> index;            result += "\":";        case JVT_PRIMARY:            if( value -> value.Type() == VT_A_STR ||                value -> value.Type() == VT_W_STR )            {                result += "\"";                result += static_cast<const char *>( value -> value );                result += "\"";            }            else            {                result += static_cast<const char *>( value -> value );            }            break;        case JVT_ARRAY:            if( value -> index.empty() == false )             {                result += "\"";                result += value -> index;                result += "\":";            }                        result += "[";            for( tagJsonKeyValue::Array::const_iterator                 it  = value -> group.begin();                 it != value -> group.end(); ++ it )            {                if( it -> second )                {                    result += Stringity( it -> second );                    result += ", ";                }            }            result += "]";            break;        case JVT_OBJECT:            if( value -> index.empty() == false )             {                result += "\"";                result += value -> index;                result += "\":";            }             result += "{";            for( tagJsonKeyValue::Array::const_iterator                 it  = value -> group.begin();                 it != value -> group.end(); ++ it )            {                if( it -> second )                {                    result += Stringity( it -> second );                    result += ", ";                }            }            result += "}";            break;        default:            break;        }    }    return result;} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::CJson atom::CJson::Clone(){    CJson result;    result.type = type;    result.root = Clone( root );    return result;} //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"atom::tagJsonKeyValue atom::CJson::Clone(const tagJsonKeyValue::Ptr & data){    tagJsonKeyValue result;    if( !data ) {        return result;    }     result.index = data -> index;    result.value = data -> value;        // 先克隆下一层的数据;    for( tagJsonKeyValue::Array::const_iterator        it1  = data -> group.begin();        it1 != data -> group.end(); ++ it1 )    {        result.group.push_back(             make_pair( it1 -> first, Clone(it1 -> second) ) );    }    return result;}

以上就是“怎么用C++编写一个Json解析器”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网其他教程频道。

--结束END--

本文标题: 怎么用C++编写一个Json解析器

本文链接: https://lsjlt.com/news/351272.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 怎么用C++编写一个Json解析器
    今天小编给大家分享一下怎么用C++编写一个Json解析器的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。之前用RapidJso...
    99+
    2023-07-05
  • 利用C++编写一个Json解析器
    之前用RapidJson来做json的解析,但是,RapidJson还是有麻烦的地方,虽然速度非常快,但是由于用了非常多的优化技巧,反而无法做到我想要的那种简便的访问方式。 比如,有...
    99+
    2023-03-10
    C++编写Json解析器 C++ Json解析器 C++ Json解析
  • 基于C++怎么编写一个Json解析器
    这篇文章主要介绍了基于C++怎么编写一个Json解析器的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇基于C++怎么编写一个Json解析器文章都会有所收获,下面我们一起来看看吧。代码JsonSerialize.h...
    99+
    2023-07-05
  • 基于C++编写一个Json解析器
    目录前言代码JsonSerialize.hJsonSerialize.cppmain.cpp前言 这个是我闲着没事写的,这个解析器还有两个问题 1.读取中文的时候会出错,这个应该是在...
    99+
    2023-03-09
    C++编写Json解析器 C++ Json解析器 C++ Json解析
  • 使用c# 怎么编写一个ORM框架
    今天就跟大家聊聊有关使用c# 怎么编写一个ORM框架,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。1. ORMORM全称 Object Relational Mapping,翻译过来...
    99+
    2023-06-14
  • 怎么用C++编写一个井字游戏
    这篇文章主要介绍“怎么用C++编写一个井字游戏”,在日常操作中,相信很多人在怎么用C++编写一个井字游戏问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么用C++编写一个井字游戏”的疑惑有所帮助!接下来,请跟...
    99+
    2023-06-17
  • 怎么编写一个shell正向解析脚本
    这期内容当中小编将会给大家带来有关怎么编写一个shell正向解析脚本,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。正向解析脚本#!/bin/bashyum install bind&n...
    99+
    2023-06-09
  • 怎么在编写一个shell分离解析脚本
    这篇文章给大家介绍怎么在编写一个shell分离解析脚本,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。分离解析脚本在运行脚本之前,需要VM虚拟机,Centos7,两台主机一台win10 -1 作为广域网的主机, 一台wi...
    99+
    2023-06-09
  • 怎么用Python编写一个拼写纠错器
    这篇文章主要介绍“怎么用Python编写一个拼写纠错器”,在日常操作中,相信很多人在怎么用Python编写一个拼写纠错器问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么用Python编写一个拼写纠错器”的疑...
    99+
    2023-06-04
  • 怎么用sql编写一个触发器
    要编写一个触发器,你需要使用SQL语言来定义触发器的逻辑。以下是一个使用SQL编写触发器的基本步骤: 创建一个触发器:使用CREA...
    99+
    2023-10-25
    sql
  • 怎么用Python编写一个装饰器
    本篇内容主要讲解“怎么用Python编写一个装饰器”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么用Python编写一个装饰器”吧!首先概念,装饰器是闭包的一种应用,需要满足一下规则:在不更改...
    99+
    2023-06-02
  • 怎么用C写一个web服务器之GCC项目编译
    这篇文章给大家分享的是有关怎么用C写一个web服务器之GCC项目编译的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。前言本想着接下来大概实现一下 CGI 协议,但是实现过程中被一个问题卡住了:C进程与php进程的交...
    99+
    2023-06-15
  • 基于C++怎么编写一个简单的服务器
    这篇文章主要讲解了“基于C++怎么编写一个简单的服务器”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“基于C++怎么编写一个简单的服务器”吧!先写个简易的controller基类继承反射基类,...
    99+
    2023-07-05
  • 怎么用c语言编写一个旋转的动画
    要使用C语言编写一个旋转的动画,可以使用图形库如OpenGL或者SDL来实现。以下是使用OpenGL库编写一个旋转的动画的示例代码:...
    99+
    2023-10-11
    c语言
  • 怎么用HTML5编写一个时钟
    这篇文章主要介绍“怎么用HTML5编写一个时钟”,在日常操作中,相信很多人在怎么用HTML5编写一个时钟问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么用HTML5编写一个...
    99+
    2024-04-02
  • 怎么用java编写一个circular类
    可以通过以下步骤来用Java编写一个Cirular类:1. 创建一个Circular类的Java文件,例如Circular.java...
    99+
    2023-10-18
    Java
  • 怎么用Python编写一个进程勾选器
    要编写一个进程勾选器(也就是监视和选择进程)的Python程序,可以使用psutil库来获取系统当前运行的进程信息,并使用tkint...
    99+
    2024-03-05
    Python
  • 基于C++编写一个文章生成器
    目录1.概况2.基本要求3.程序分析3.1 文件流读写3.2 建立前后缀关系3.3 字符串切片3.4 变长数组4.代码实现4.1 函数:数组加长4.2 类wordpair定义4.3 ...
    99+
    2023-03-19
    C++文章生成器 C++文章生成 C++生成器
  • 用c语言编写一个通讯录代码详解
    目录实现通讯录的思路如下:总结实现通讯录的思路如下: 1.程序运行起来时用户首先要看到菜单栏选项并且对应菜单栏所给出的选项做出选择,这里我们简单设计一个Menu()函数可以让用户看见...
    99+
    2024-04-02
  • 怎么用Java编写一个小程序
    编写Java小程序的步骤如下:1. 安装Java开发工具包(JDK):从Oracle官网下载并安装最新版本的JDK。2. 配置开发环...
    99+
    2023-10-18
    java
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作