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<std::string> 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 <iostream>
#include <fstream>
#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"<<std::endl;
	else
    	std::cout<<"Year is not a member"<<std::endl;
	
	if(root["Week"].isArray())
    	std::cout<<"Week is a array"<<std::endl;
	else
    	std::cout<<"Week is not a array"<<std::endl;
	
	if(root["People"].empty())
    	std::cout << "People is empty" <<std::endl; 
	else
		std::cout << "People is not empty" <<std::endl;
}
int main(void)
{
	js_read();
	js_write();
	js_other();
	return 0;
}
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 
整个工程目录树如下:

4. 4 执行结果

 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号