rapidjson使用笔记

rapidjson是什么? 参考http://rapidjson.org/ 不赘述

通过最近几天的开发任务我使用rapidjson 实现了windows下的json文件的读取,分析参数,改写参数 以及后期可能添加的参数的插入和删除。

开发平台:windows 语言 :C++

1.文件操作 方面主要是文件的读取和写入,为了方便操作 我将文件的读取和写入分别封装成了函数。
文件的读取函数

string get_filecontent(const char* filePath)
{
    std::string fileDir(file_topdir);// 获取顶层头文件 方便使用相对路径
    fileDir.append(filePath); // 生成路径相关的字符串,方便去访问文件
    std::ifstream in(fileDir.data()); // 文件的读取操作, copy的  不解释
    if(!in.is_open()){   
        printf("err here:%s,%d\r\n",__FILE__,__LINE__);
        printf("faild open %s\r\n",fileDir.data());
    }  
    std::string json_content((std::istreambuf_iterator<char>(in)), \
                    std::istreambuf_iterator<char>());
    //将文件的数据流转换位std::string类型
    //cout<<json_content<<endl; 
    in.close();  // 关闭文件
    return json_content;//将处理之后的std::string 返回
}

以上就是关于文件读取的函数,通过这个函数 我们可以将json文件读取到string 中,方便接下来的json操作。
文件的写入函数:

bool prettyWritefile(const char *relatedPath , rapidjson::Document &document)
{
    rapidjson::StringBuffer buffer;  
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);  
    //PrettyWriter  这个词很关键 如果只是Write的话  写入的结构会比较难看,但是更省空间?
    document.Accept(writer);  //将json的数据流写入 writer?
    std::string Path(file_topdir);  // 将文件顶层路径转换位std::string 类型
    Path.append(relatedPath);       // 添加相对路径
    std::string temp(buffer.GetString());
    std::ofstream outfile;
    outfile.open(Path.data());
    if(outfile.fail()){
        printf("open file %s error\r\n",Path.data());
        printf("err here: %s,%d\r\n",__FILE__,__LINE__);
        return false;
    }else{
        outfile<<temp;
        outfile.close();
        return true;
    //关于文件写入部分,确实不熟悉,不去过多的解释,抛砖引玉吧。
    //抄的那里的代码也忘了  实在抱歉
    }
}

通过上述的两个函数我们可以实现文件的读写了,接下来就是针对与文件之内的数据流进行操作,通过rapidjson,我们可以获得json中的数据,也可以修改json的数据。
json 我处理的json文件 是这个

{
    "Int": 123,
    "Double": 15.100000099999999,
    "String": "changed",
    "Object": {
        "name": "lihua",
        "age": 25
    },
    "IntArray": [
        27,
        37,
        47
    ],
    "DoubleArray": [
        5.9999999999999968,
        6.9999999999999968,
        7.999999999999997
    ],
    "StringArray": [
        "one",
        "two",
        "three"
    ],
    "MixedArray": [
        "one",
        50,
        false,
        12.005
    ],
    "People": [
        {
            "name": "zhangsan",
            "age": 33,
            "sex": true
        },
        {
            "name": "lisi",
            "age": 44,
            "sex": false
        },
        {
            "name": "wangwu",
            "age": 55,
            "sex": true
        }
    ],
    "operate_cnt": 40
}

json 文件引用自 https://www.cnblogs.com/fnlingnzb-learner/p/10334988.html 我对文件中的内容进行了比较大的修改
关于json修改部分的代码 以及整个工程的逻辑

#include <iostream>
#include "./rapidjson/include/document.h"
#include "./rapidjson/include/stringbuffer.h"
#include "./rapidjson/include/prettywriter.h"
#include "./rapidjson/include/filereadstream.h"
#include "./rapidjson/include/filewritestream.h"
#include "./rapidjson/include/writer.h"
#include <fstream>
#define file_topdir  "./"  
//#define file_name  "my_test.json"
using namespace std;


// ide ::vscode
// 编译环境  cmake + mingw 
//cmake -G "MinGW Makefiles" ..
//mingw32-make

string get_filecontent(const char* filePath)
{
    std::string fileDir(file_topdir);// 获取顶层头文件 方便使用相对路径
    fileDir.append(filePath); // 生成路径相关的字符串,方便去访问文件
    std::ifstream in(fileDir.data()); // 文件的读取操作, copy的  不解释
    if(!in.is_open()){   
        printf("err here:%s,%d\r\n",__FILE__,__LINE__);
        printf("faild open %s\r\n",fileDir.data());
    }  
    std::string json_content((std::istreambuf_iterator<char>(in)), \
                    std::istreambuf_iterator<char>());
    //将文件的数据流转换位std::string类型
    //cout<<json_content<<endl; 
    in.close();  // 关闭文件
    return json_content;//将处理之后的std::string 返回
}

bool prettyWritefile(const char *relatedPath , rapidjson::Document &document)
{
    rapidjson::StringBuffer buffer;  
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);  
    //PrettyWriter  这个词很关键 如果只是Write的话  写入的结构会比较难看,但是更省空间?
    document.Accept(writer);  //将json的数据流写入 writer?
    std::string Path(file_topdir);  // 将文件顶层路径转换位std::string 类型
    Path.append(relatedPath);       // 添加相对路径
    std::string temp(buffer.GetString());
    std::ofstream outfile;
    outfile.open(Path.data());
    if(outfile.fail()){
        printf("open file %s error\r\n",Path.data());
        printf("err here: %s,%d\r\n",__FILE__,__LINE__);
        return false;
    }else{
        outfile<<temp;
        outfile.close();
        return true;
    //关于文件写入部分,确实不熟悉,不去过多的解释,抛砖引玉吧。
    //抄的那里的代码也忘了  实在抱歉
    }
}

int main(void)
{
    std::string json_content=get_filecontent("my_test.json");
    rapidjson::Document document;
    if (document.Parse(json_content.c_str()).HasParseError()) { //判断语法是否有问题
		printf("err here %s,%d\r\n",__FILE__,__LINE__);           
    }else{  
        if(!(document.HasMember("operate_cnt"))) {// 每次操作都将这个值加一
            printf("err here:%s,%d\r\n",__FILE__,__LINE__);
        }else{
            document["operate_cnt"] = document["operate_cnt"].GetInt() +1;
            cout<<"document[\"operate_cnt\"] = "<<document["operate_cnt"].GetInt()<<endl;
        }
        if(!(document.HasMember("Int"))){  // int 类型的操作
            printf("do not have member\r\n");
        }else{
            cout<<"Int = "<<document["Int"].GetInt()<<endl; //参数的读取
            document["Int"] = 123;
            cout<<"Int = "<<document["Int"].GetInt()<<endl;            
        }
        if(!(document.HasMember("Double"))){// Double 类型的操作
            printf("do not have member\r\n");
        }else{
            cout<<"Double = "<<document["Double"].GetDouble()<<endl; //参数的读取
            document["Double"]
             = document["Double"].GetDouble() + 0.1;
            cout<<"Double = "<<document["Double"].GetDouble()<<endl;            
        }
        if(!(document.HasMember("String"))){// String 类型的操作
            printf("do not have member\r\n");
        }else{
            document["String"] =  "changed";
            cout<<"String = "<<document["String"].GetString()<<endl;            
        }
        if(!(document.HasMember("Object"))){ //操作嵌套对象
            printf("do not have member\r\n");
        }else{
            const rapidjson::Value& object = document["Object"];
            cout<<"name : "<<object["name"].GetString()<<endl;
            cout<<"age  : "<<object["age"].GetInt()<<endl;
        }
        if(!(document.HasMember("IntArray"))){ //操作 int 数组
            printf("do not have member\r\n");
        }else{
            rapidjson::Value& IntArray = document["IntArray"]; // 若不修改  可以加const
            for(int i=0;i<IntArray.Size();i++){
                printf("IntArray[%d] = %d\r\n",i,IntArray[i].GetInt());
                IntArray[i] = (1 + IntArray[i].GetInt() ); 
            }
        }
        if(!(document.HasMember("DoubleArray"))){ //操作 double 数组
            printf("do not have member\r\n");
        }else{
            rapidjson::Value& DoubleArray = document["DoubleArray"]; // 若不修改  可以加const
            for(int i=0;i<DoubleArray.Size();i++){
                printf("DoubleArray[%d] = %f\r\n",i,DoubleArray[i].GetDouble());
                DoubleArray[i] = (0.1 + DoubleArray[i].GetDouble() ); 
            }
        }
        if(!(document.HasMember("StringArray"))){ //操作字符数组,
            printf("do not have member\r\n");
        }else{
            rapidjson::Value& StringArray = document["StringArray"]; // 若不修改  可以加const
            for(int i=0;i<StringArray.Size();i++){
                cout<< StringArray[i].GetString()<<endl;
            }
        }
        if(!(document.HasMember("MixedArray"))){//操作 混合数组
            printf("do not have member\r\n");
        }else{
            rapidjson::Value& MixedArray = document["MixedArray"]; // 若不修改  可以加const
            for(int i=0;i<MixedArray.Size();i++){
                if(MixedArray[i].IsBool()){
                    //懒得分析
                }else if(MixedArray[i].IsDouble()){
                    printf("No.%d params of MixedArray is double, val = %f\r\n",\
                                    i,MixedArray[i].GetDouble());    
                }else if(MixedArray[i].IsInt()){
                    printf("No.%d params of MixedArray is int, val = %d\r\n",\
                                    i,MixedArray[i].GetInt());
                } else{
                        //不去分析了  一样的
                }                    
            }
             if(!(document.HasMember("People")&&document["People"].IsArray())){
                        printf("do not have member or not array\r\n");
            }else{
                rapidjson::Value &People = document["People"];//操作 数组项是对象的嵌套类型
                for(int i=0;i<People.Size();i++)
                {
                    rapidjson::Value &someone = People[i];
                    if(!someone.HasMember("name")){
                        printf("err here:%d,this one no name!\r\n",__LINE__);
                    }else{
                        printf("name[%d] = %s\r\n ",i,someone["name"].GetString());
                    }
                    if(!someone.HasMember("age")){
                        printf("err here:%d,this one no age!\r\n",__LINE__);
                    }else{
                        printf("age[%d] = %d\r\n ",i,someone["age"].GetInt());
                    }
                    if(!someone.HasMember("sex")){
                        printf("err here:%d,this one no sex!\r\n",__LINE__);
                    }else{
                        printf("sex[%d] = %s\r\n ",i,(someone["sex"].GetBool()?"male":"female"));
                    }
                }
            }
        }
    }
    prettyWritefile("my_test.json",document);  // 将修改之后的文件写磁盘
    printf("success!\r\n");
    std::string s;
    std::cin>>s; // 卡住cmd 看打印信息
    return 0;
}

//cmake -G "MinGW Makefiles" ..
//mingw32-make

cmake 配置项

# BuildDefaults.cmake
# Setup default build options
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})

include(Configs)
include(BuildOptions)
include(Install)

#BuildOptions.cmake
# Set up the compiler flags.
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_VERBOSE_MAKEFILEON ON)

# Determine the platform and compiler dependent flags.
set(CXX_PLATFORM_DEPENDENT_FLAGS_DEBUG      "/DDEBUG i-DACSDK_DEBUG_LOG_ENABLED /W4 /Zi")
set(CXX_PLATFORM_DEPENDENT_FLAGS_RELEASE    "/DNDEBUG /W4 /O2")
set(CXX_PLATFORM_DEPENDENT_FLAGS_MINSIZEREL "/DNDEBUG /W4 /O1")

# Debug build, default.
set(CMAKE_CXX_FLAGS_DEBUG "${CXX_PLATFORM_DEPENDENT_FLAGS_DEBUG} -DRAPIDJSON_HAS_STDSTRING" CACHE INTERNAL "Flags used for DEBUG builds" FORCE)
set(CMAKE_C_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG} CACHE INTERNAL "Flags used for DEBUG builds" FORCE)
#CMakeLists.txt
cmake_minimum_required(VERSION 3.1 FATAL_ERROR)

# Set project information
project(controller VERSION 0.0.0 LANGUAGES CXX)
include(cmakes/BuildDefaults.cmake)



add_executable(test 
                 test.cpp
                 
                 
                 )
# src targets.

工程会打包同步上传,才疏学浅,难免有疏漏,希望大佬们不吝赐教!

GitHub 加速计划 / js / json
41.72 K
6.61 K
下载
适用于现代 C++ 的 JSON。
最近提交(Master分支:9 天前 )
960b763e 2 个月前
8c391e04 5 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐