json 与 string 的转换

今天和一个客户平台进行联调,其中平台下发的数据文档说明如:

json 与 string 的转换_第1张图片

一开始我当成数组来解析,以为是文档写错了(因为有些接口返回值类型跟文档不对应,也没去纠结了,只是看实际返回类型),后来实际返回的真是如上数据类型,不解的是data直接是数组就可以了,为何要变成字符串呢?跟他们确认,小伙就说是json数组。data值是字符串,以为要自己解析了,仔细一看这个data就是一个json类型的string,只要把string转换成json就可以了。

 如有文件内容:

 main 函数如下:

int main()
{
    Json::Value json;
    if(readConfig("personList", json))
    {
        printf("json[data].type = %d\n", json["data"].type());

        Json::Value personlist;
        std::string data = json["data"].asString();
        if(stringToJson(data, personlist))
        {
            printf("personlist size = %u, personlist = %s\n", personlist.size(), personlist.toStyledString().c_str());
        }
    }
    
    return 0;
}

能看到先取出data的值:std::string data = json["data"].asString();

然后再把string 转换成 json:stringToJson(data, personlist),最后执行结果为:

json 与 string 的转换_第2张图片

 为什么数组就可以下发下来,却要转成string下发?有一种可能是平台组好数据后,一次性把数据转换成不带换行符、制表符、空格的string。

如下的函数:
 

/**
 * @brief 格式化joson字符
 * @indent 缩进方式: ""为空时不包含换行和空格、"\t"制表tab、" "空格等
 * @outStr 
 * @return 
 */
int32_t toStyledString(const Json::Value &json, std::string &indent, std::string &outStr)
{
    std::stringstream os;
    Json::StreamWriterBuilder builder;
    builder["indentation"] = indent;
    std::unique_ptr streamWriter(builder.newStreamWriter());
    int32_t iRet = streamWriter->write(json, &os);
    if(iRet == 0)
    {
        outStr = os.str();
    }

    return iRet;
}

然后用这个函数将上面文件中读取的数据转换成如下:
json 与 string 的转换_第3张图片

 格式化后的字符大小比原文件的大小还大,还是不解。。。。

完整代码:

///用到的json库需要自行编译
#include 
#include 
#include 

bool readConfig(const char *file, Json::Value &result);
bool readBuffer(const char *buf, Json::Value &json);
bool stringToJson(std::string &str, Json::Value &outJson);
int32_t toStyledString(const Json::Value &json, std::string &indent, std::string &outStr);

int main()
{
    Json::Value json;
    if(readConfig("personList", json))
    {
        printf("json[data].type = %d\n", json["data"].type());

        Json::Value personlist;
        std::string data = json["data"].asString();
        if(stringToJson(data, personlist))
        {
            printf("personlist size = %u, data.size = %lu, personlist = %s\n", personlist.size(), data.size(), personlist.toStyledString().c_str());
        }
    }
    

    std::string indent("");
    std::string outStr;
    toStyledString(json, indent, outStr);
    printf("outStr.size = %lu, styledString = %s\n", outStr.size(), outStr.c_str());
    return 0;
}

bool readConfig(const char *file, Json::Value &result)
{
    Json::CharReaderBuilder readBuilder;
    std::unique_ptr reader(readBuilder.newCharReader());

    int32_t fileSize = 0;
    char *buffer = nullptr;

    std::ifstream configFile(file, std::ios::in | std::ios::binary | std::ios::ate);
    if(configFile.good())
    {
        fileSize = configFile.tellg();
        buffer = new char[fileSize + 1];
        configFile.seekg(0, std::ios::beg);
        configFile.read(buffer, fileSize);
        configFile.close();
    }
    std::cout << "file size: " << fileSize << std::endl;
    std::string err;
    bool iRet = reader->parse(buffer, buffer + fileSize, &result, &err);
    if(!iRet)
    {
        printf("json parse fail, msg = %s\n", err.c_str());
    }
    if(buffer != nullptr)
    {
        delete []buffer;
    }

    return iRet;
}

bool readBuffer(const char *buf, Json::Value &json)
{    
    if(buf == nullptr)
    {
        return false;
    }
    Json::CharReaderBuilder readBuilder;
    std::unique_ptr reader(readBuilder.newCharReader());

    int32_t len = strlen(buf);
    char *buffer = nullptr;

    if(len > 0)
    {
        buffer = new char[len + 1];
        memcpy(buffer, buf, strlen(buf));
    }

    std::string err;
    bool iRet = reader->parse(buffer, buffer + len, &json, &err);
    if(!iRet)
    {
        printf("json parse fail, msg = %s\n", err.c_str());
    }

    if(buffer != nullptr)
    {
        delete []buffer;
    }
    
    return iRet;
}


bool stringToJson(std::string &str, Json::Value &outJson)
{
    return readBuffer(str.c_str(), outJson);
}

/**
 * @brief 格式化joson字符
 * @indent 缩进方式: ""为空时不包含换行和空格、"\t"制表tab、" "空格等
 * @outStr 
 * @return 
 */
int32_t toStyledString(const Json::Value &json, std::string &indent, std::string &outStr)
{
    std::stringstream os;
    Json::StreamWriterBuilder builder;
    builder["indentation"] = indent;
    std::unique_ptr streamWriter(builder.newStreamWriter());
    int32_t iRet = streamWriter->write(json, &os);
    if(iRet == 0)
    {
        outStr = os.str();
    }

    return iRet;
}

你可能感兴趣的:(c/c++,json,c语言,http)