c/c++使用cJson解析未知内容的json字符串

版权声明:所有版权归作者她的吻让他,转载请标明出处. https://blog.csdn.net/qq_37059136/article/details/82883090

关于json我这里就不做缀饰,这里给出链接百度百科json

我这里只介绍下json中的符号格式

{ } : 双括号表示一个json对象。例如:{"name":"ljl"},这代表一个name为ljl的对象

[ ] : 中括号表示数组。例如:[{"name","ljl"},{"memory","ljx"}],表示包含两个对象的数组

 :冒号表示后者是前者的值。比如我上面的{"name":"ljl"},ljl是name的值

" " :双引号内是属性或值。例如{"date","18-09-28"},属性是date,它的值是18-09-28

,  :逗号表示间隔,常用于两个对象之间。如[{"name","ljl"},{"memory","ljx"}]

json在java中使用比较容易,一般在c/c++中不使用该格式,但有时项目会涉及到前端用c/c++去编写而后端用Java编写,这两者间通信时一般都选用Json格式

c/c++中能够解析、创建Json字串的工具(或者说方法)不多,目前笔者只找到cJson跟Jsoncpp两种简单方法。其中cJson最为方便,这里使用cJson做为解析、创建Json的工具

如果没有cJson,本文给出下载链接cJson下载

将cJson.h和cJson.c添加到项目并包含路径即可使用(注意:.c文件必须添加至项目,否则不会编译)

test.c文件为官方演示测试文件,里面有一些函数的简单用法

下面展示下如何解析已知结构的简单Json字串

#include <iostream>
#include "cJSON.h"
#include <string>
#include <Windows.h>
#include <map>
using namespace std;


int main()
{

	string json_string = "{\"ResCode\":\"000\",\"ResDesc\":\"业务受理成功\",\"ServiceResMsg\":\"这是XML格式字串\"}";

	//JSON字符串到cJSON格式
	cJSON* cjson1 = cJSON_Parse(json_string.c_str()); 
	//判断cJSON_Parse函数返回值确定是否打包成功
	if(cjson1 == NULL)
	{
		printf("json pack into cjson error...");
	}
	else
	{
		//打包成功调用cJSON_Print打印输出

		cJSON_Print(cjson1);                    // 将json形式打印成正常字符串形式
	}

	//获取字段值
	//cJSON_GetObjectltem返回的是一个cJSON结构体所以我们可以通过函数返回结构体的方式选择返回类型!
	string _1_string = cJSON_GetObjectItem(cjson1,"ResCode")->valuestring;
	string _2_string = cJSON_GetObjectItem(cjson1,"ResDesc")->valuestring;
	string _3_string = cJSON_GetObjectItem(cjson1,"ServiceResMsg")->valuestring;


	cout << _1_string << endl;
	cout << _2_string << endl;
	cout << _3_string << endl;
	//delete cjson
	cJSON_Delete(cjson1);

    return 0;
}

代码中

    string _1_string = cJSON_GetObjectItem(cjson1,"ResCode")->valuestring;
    string _2_string = cJSON_GetObjectItem(cjson1,"ResDesc")->valuestring;
    string _3_string = cJSON_GetObjectItem(cjson1,"ServiceResMsg")->valuestring;

通过调用cJSON_GetObjectItem函数将已知结构,比如ResCode,ResDesc,ServiceResMsg三个节点的值读出来

关于复杂的Json字串解析,诸如包含数组的,可以去其他csdn查看,有些博客写的还是很到位的,我这里主要讲解析未知内容的Json字串

笔者研究了下cJson.c跟cJson.h文件,貌似没有发现可以直接解析未知Json字串的方法,但笔者在cJson.h中找到了官方定义的结构体

typedef struct cJSON {
	struct cJSON *next,*prev;	/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
	struct cJSON *child;		/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */

	int type;					/* The type of the item, as above. */

	char *valuestring;			/* The item's string, if type==cJSON_String */
	int valueint;				/* The item's number, if type==cJSON_Number */
	double valuedouble;			/* The item's number, if type==cJSON_Number */

	char *string;				/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
} cJSON;

笔者稍微研究了下cJSON *cJSON_GetObjectItem(cJSON *object,const char *string)函数

cJSON *cJSON_GetObjectItem(cJSON *object,const char *string)	
{
    cJSON *c=object->child; 
    while (c && cJSON_strcasecmp(c->string,string)) 
    c=c->next; 
    return c;
}

该函数内部实现的是通过遍历cJson的对象中struct cJSON *child中的struct cJSON *next,*prev来达成遍历Json字串的目的

下面我们就通过这种方法自己写一个接口函数,实现解析未知结构、内容的Json字串

#include <iostream>
#include "cJSON.h"
#include <string>
#include <Windows.h>
#include <map>
using namespace std;



map<string,string> MapAnalysisJSON(string ResMessage)
{
	map<string,string> mapResMessage;

	cJSON* cjson = cJSON_Parse(ResMessage.c_str()); 

	if(cjson == NULL)
	{
		printf("json pack into cjson error...");
	}
	else
	{
		cJSON_Print(cjson);              
	}

	cJSON * c = cjson->child;
	while (c)
	{
		mapResMessage.insert(pair<string,string>(c->string,c->valuestring));
		c = c->next;
	}
	c = NULL;

	return mapResMessage;

}


int main()
{
	string json_string = "{\"ResCode\":\"000\",\"ResDesc\":\"业务受理成功\",\"ServiceResMsg\":\"这是XML格式字串\"}";
	map<string,string> recmap;


    recmap = MapAnalysisJSON(json_string);

	if (recmap.size() == 0)
	{
		cout << "recmap is empty!";
	}

	for (map<string,string>::iterator iter = recmap.begin();iter != recmap.end();iter++)
	{
		cout << iter->first << " " << iter->second << endl;
	}



	return 0;
}

我这里将未知Json字串解析成map对象

map跟Json的理念有点相似即一个键对应一个值,当然你也可以将Json解析成你想要的任何格式

猜你喜欢

转载自blog.csdn.net/qq_37059136/article/details/82883090