jsoncpp应用(Linux环境)

  目前考虑需使用C++操作JSON串,避免重复造轮子,GitHub上有不少开源好使的C++ JSON库。如jsoncpp、frozen 、JSON++ 、JeayeSON、PicoJSON等等,经过对比分析,发现“jsoncpp”是一个应用比较广、开源、轻量级的json库,也不乏各类学习资料,参与维护者多,如果存在bug时也能及时发现。

jsoncpp 源码:
https://github.com/open-source-parsers/jsoncpp
https://sourceforge.net/projects/jsoncpp/postdownload

  jsoncpp使用也比较容易上手,网络上也不少教程,以下文章要参考各大网络博客总结完成。jsoncpp主要包括三个类(class),Value、Reader、Writer,对应于三个json_value.cpp、json_write.cpp、json_read.cpp及对应的头文件。

1.Value 类

  Value类是jsoncpp最基本的也是最常用的类,用于创建JSON串对象、对象赋值、对象交换、JSON大小比较、键值赋值等。

1.1 创建对象/键值和赋值

Json::Value root;      /* 创建json对象 */
root["Name"] = Json::Value("Acuity");		/* 新建一个键值, 赋值 字符串 */
root["Increase"] = Json::Value(180);		/* 新建一个键值,赋值数字 */
root["Array"].append("string0");  			/* 新建一个数组键值,对第一个元素赋值 */
root["Array"].append(23); 					/* 对数组键值第二个元素赋值 */

1.2 获取对象类型

Json::ValueType type = root.type();      	/* 获得 root 的类型 */

1.3 判断Key是否存在

bool Json::Value::isMember ( const char * key) const

1.4 检查Value类型,如null、bool、array等

  bool isNull() const;
  bool isBool() const;
  bool isInt() const;
  bool isInt64() const;
  bool isUInt() const;
  bool isUInt64() const;
  bool isIntegral() const;
  bool isDouble() const;
  bool isNumeric() const;
  bool isString() const;
  bool isArray() const;
  bool isObject() const;

1.5 获取所有Key

Members getMemberNames() const;

  Members原型为:typedef std::vector Json::Value::Members
即是一个值为string的vector,通过getMemberNames得到所有的key。

1.6 删除成员

Value Json::Value::removeMember( const char* key) 

2.Reader类

  Json::Reader 主要功能是将JSON字符解析为 jsoncpp的Json::Value 对象。

Json::Reader reader;
Json::Value root;
 const char* json_str = "{\"Year\" : 2019,\"Mon\":7}";
if (reader.parse(json_str , root))
{
 	 std::cout << root["Year"] << std::endl;
 	 std::cout << root["Mon"] << std::endl;
}

3.Writer类

  Json::Writer 类是把Json::Value对象写到string对象中。需要注意的是,Json::Writer是个抽象纯虚类,只作为父类继承,不能调用;其被两个子类Json::FastWriter和Json::StyledWriter继承。 两个子类功能差异是,FastWriter就是无格式的写入,所以比较“快”,但这样的JSON串看起来很乱没有格式;而StyledWriter是带有缩进、排版等格式的写入,牺牲一定的效率,使得比较方便用户阅读(友好)。

(网络)传输过程的JSON串通常使用的是“FastWriter”格式。

Json::FastWriter fw;
std::cout << fw.write(root) << std::endl;

Json::StyledWriter sw;
std::cout << sw.write(root) << std::endl;

4.应用例程

4.1 jsoncpp库编译
  目前jsoncpp最新版本是1.8.4,该版本需C++11以上的编译器支持。由于本人Linux环境比较旧,所以下载的是0.5.0的版本。后续再搭建1.8.4版本环境。使用过程遇到小插曲,本来想直接将源码拷贝到工程下编译,经过一番折腾还是编译不过,不知道啥回事。后面只能将jsoncpp编译成库文件,然后使用。当然,实际使用也建议编译成库文件(静态库/动态库),方便项目的拓展。

编译命令:

tar -zxvf jsoncpp-src-0.5.0.tar.gz
cd jsoncpp-src-0.5.0
scons platform=linux-gcc

在“/libs/linux-gcc-4.4.3”目录下生成静态库和动态库文件,名字后面接着编译器(gcc)版本。
在这里插入图片描述
4. 2 编写测试例程

#include 
#include 
#include "../include/json/json.h"	/* 暂用绝对路径,用相对路径出错,Makefile指定路径依然出错 */

using namespace std;

/* JSON字符串 */
const char *js_info ={ 		\
	"{						\
	  	\"Year\": 2019,		\
	 	\"Mon\": 6,			\
	  	\"Week\":[			\
	  	\"Sunday\", \"Monday\"],	\
	  	\"People\":{			\
	  	\"Name\":\"Acuity\",	\
	  	\"Increase\":180,		\
	  	\"English name\":null,	\
	  	\"Crime\":false,		\
				  }				\
	}"	
};

/* Json::Reader 类 */
void js_read(void)
{
	Json::Value root;
	Json::Reader reader;
	
	if(reader.parse(js_info,root))
	{
		printf("parse failed\r\n");
		return;
	}

	std::cout << "Reader  Parse json string:" << std::endl;
	std::cout << root["Year"] << std::endl;
	std::cout << root["Week"] << std::endl;
	std::cout << root["People"] << std::endl;
}

/* Json::Writer 类 */
void js_write(void)
{
	Json::Value root;
    Json::Value people;
	Json::FastWriter fw;
	Json::StyledWriter sw;
	
	root["Year"] = "2019";
	root["Mon"]  = Json::Value("6");
	root["Week"].append("Sunday");  
	root["Week"].append("Monday"); 
	
	people["Name"] = "Acuity";	
	people["Increase"] = "180";
	root["People"] = people; /* 对象嵌套 */

    /* 调用Json::FastWriter格式JSON串 */
    cout << "Json::FastWriter:" << endl;
    cout << fw.write(root) << endl;

	/* 调用Json::StyledWriter格式JSON串 */
	cout << "Json::StyledWriter:" << endl;
    cout << sw.write(root) << endl;

	/* 输出到文件 */
    ofstream fd;
    fd.open("js_test.json");
    fd << sw.write(root);
    fd.close();
}

void js_other(void)
{
	Json::Value root;
	Json::Reader reader;
	
	if(reader.parse(js_info,root))
	{
		printf("parse failed\r\n");
		return;
	}	

	if(root.isMember("Year"))
    	std::cout<<"Year is a member"<

4. 3 Makefile
  这里采用的是静态链接库的链接方式,方便运行测试。如用动态链接,需拷贝动态库到环境变量目录下或者软链接到当前库文件目录。

VERSION 	=

CC			=g++
DEBUG 		=
CFLAGS		=-Wall -c
SOURCES	 	=$(wildcard ./src/*.cpp)
INCLUDES  	=-I./include/json
LIB_NAMES 	=-ljson_linux-gcc-4.4.3_libmt
LIB_PATH 	=-L./jsonlib	 	
OBJ			=$(patsubst %.cpp, %.o, $(SOURCES))
TARGET		=js-test
	
#links
$(TARGET):$(OBJ)
	@mkdir -p output
	$(CC) $(OBJ) $(LIB_PATH) $(LIB_NAMES) -o output/$(TARGET)$(VERSION)
	@rm -rf $(OBJ)

#compile
%.o: %.c
	$(CC) $(INCLUDES) $(DEBUG) $(CFLAGS) $^ -o $@
	
.PHONY:clean
clean:
	@echo "Remove linked and compiled files......"
	rm -rf $(OBJ) $(TARGET) output 

整个工程目录树如下:
jsoncpp应用(Linux环境)_第1张图片
4. 4 执行结果
jsoncpp应用(Linux环境)_第2张图片

你可能感兴趣的:(JSON,C/C++编程,物联网)