欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Boost学习之读写json

程序员文章站 2024-03-14 11:10:16
...


昨天写了《Boost学习之读写ini文件》,发现boost不止可以读写ini文件,还可以很方便的读写json文件。之前在C++中读写json比较抽象,从boost的语法可以很轻松的看出来。与读写ini一样,json格式,在boost中也被抽象为property_tree

Boost中Json数据类型

在构建json文件时,我们只需要构建多个tree节点,按照对应的树形结构组合在一起即可。从boost写json文件API源码可以看出,property_tree支持三种类型,分别是valuearrayobject

  • value:系统默认数据类型;
  • array:数组类型,可以嵌套自定义类型,在方括号中存放。
  • object:使用者自定义的数据类型,在花括号中存放。

Boost写Json核心源码

以下代码段,是boost写入json核心代码。

 template<class Ptree>
    void write_json_helper(std::basic_ostream<typename Ptree::key_type::value_type> &stream, 
                           const Ptree &pt,
                           int indent, bool pretty)
    {

        typedef typename Ptree::key_type::value_type Ch;
        typedef typename std::basic_string<Ch> Str;

        // Value or object or array
        if (indent > 0 && pt.empty())
        {
            // Write value
            Str data = create_escapes(pt.template get_value<Str>());
            stream << Ch('"') << data << Ch('"');

        }
        else if (indent > 0 && pt.count(Str()) == pt.size())
        {
            // Write array
            stream << Ch('[');
            if (pretty) stream << Ch('\n');
            typename Ptree::const_iterator it = pt.begin();
            for (; it != pt.end(); ++it)
            {
                if (pretty) stream << Str(4 * (indent + 1), Ch(' '));
                write_json_helper(stream, it->second, indent + 1, pretty);
                if (boost::next(it) != pt.end())
                    stream << Ch(',');
                if (pretty) stream << Ch('\n');
            }
            if (pretty) stream << Str(4 * indent, Ch(' '));
            stream << Ch(']');

        }
        else
        {
            // Write object
            stream << Ch('{');
            if (pretty) stream << Ch('\n');
            typename Ptree::const_iterator it = pt.begin();
            for (; it != pt.end(); ++it)
            {
                if (pretty) stream << Str(4 * (indent + 1), Ch(' '));
                stream << Ch('"') << create_escapes(it->first) << Ch('"') << Ch(':');
                if (pretty) stream << Ch(' ');
                write_json_helper(stream, it->second, indent + 1, pretty);
                if (boost::next(it) != pt.end())
                    stream << Ch(',');
                if (pretty) stream << Ch('\n');
            }
            if (pretty) stream << Str(4 * indent, Ch(' '));
            stream << Ch('}');
        }

    }

简单的Json示例

构造简单Json示例

看完源码,下面将按照三种不同类型构造一个简单地json文件

void build_json()
{ 
	ptree root; // 根节点
	ptree arr;
	root.put("version", 1);  // value类型,一级节点

	// 二级节点
	ptree node1, node2, node3, node4, node5;
	node1.put("frame_rate", 0);
	node1.put("bit_rate", 1);
	node1.put("resolution", 3);
	node1.put("boot", 0);
	node1.put("ssfs", 2);

	// 添加二级节点
	root.add_child("0", node1);
	root.add_child("1", node1);
	root.add_child("2", node1); 
	
	stringstream s;
	write_json(s, root, false);
	string out = s.str();

	ofstream oftream("config_json.json", std::ios_base::out);
	oftream << out;
	oftream.close(); 
}

运行结果

{
	"version": "1",
	"0": {
		"frame_rate": "0",
		"bit_rate": "1",
		"resolution": "3",
		"boot": "0",
		"ssfs": "2"
	},
	"1": {
		"frame_rate": "0",
		"bit_rate": "1",
		"resolution": "3",
		"boot": "0",
		"ssfs": "2"
	},
	"2": {
		"frame_rate": "0",
		"bit_rate": "1",
		"resolution": "3",
		"boot": "0",
		"ssfs": "2"
	}
}
简单Json解析示例

一般有写入就有读取,下面示例代码,将结合上述json结构,读取相关信息,并打印

void Read_json()
{
	ifstream ifstrema("config_json.json", std::ios_base::in);

	ptree node;   //初始化根节点
	
	read_json(ifstrema, node); // 将json文件读入根节点

	int intVersion = node.get<int>("version"); // 获取一级节点“version”的值

	ptree temp = node.get_child("0"); // 获取一级节点“0”的子节点信息
	
	// 迭代一级节点的子节点中的每个项
	for (boost::property_tree::ptree::iterator it = temp.begin(); it != temp.end(); ++it)
	{
		cout << "first:" << it->first << endl;          // key
		cout << "second:" << it->second.data() << endl; // value
	}
}

运行结果
Boost学习之读写json
可以看出,json是按照键值对存储,读取时,通过键获取相对应的值。

较复杂的Json示例

构造较复杂的Json
void build_json()
{ 
	ptree root, node1, object;
	ptree arr;
	ptree arrv1, arrv2, arrv3; 
	 
	// value 类型
	root.put("version", 1);

	bool boolvalue = true;
	root.put("boolean", boolvalue);

	root.put("null", "null");
	root.put("tip", "Hello World");

	node1.put("frame_rate", 0);
	node1.put("bit_rate", 1);
	node1.put("resolution", 3);
	node1.put("boot", 0);
	node1.put("ssfs", 2);

	root.add_child("0", node1);
	root.add_child("10", node1);
	root.add_child("20", node1);

	// arry类型
	arrv1.put("a", "b");
	arrv2.put("Tom", "23");
	arrv3.put("Tony", "4");
	arrv1.put("marble", "2222");
	
	arr.push_back(std::make_pair("", arrv1));
	arr.push_back(std::make_pair("", arrv2));
	arr.push_back(std::make_pair("", arrv3));

	// object类型
	object.put("a", "b");
	object.put("c", "d");
	object.put("e", "f");
	
	root.add_child("1", arr);
	root.add_child("2", arr);
	
	root.add_child("object", object);

	stringstream s;
	write_json(s, root, false);
	string out = s.str();

	ofstream oftream("config_json.json", std::ios_base::out);
	oftream << out;
	oftream.close();
	cout << out;
}

执行结果

{
	"version": "1",
	"boolean": "true",
	"null": "null",
	"tip": "Hello World",
	"0": {
		"frame_rate": "0",
		"bit_rate": "1",
		"resolution": "3",
		"boot": "0",
		"ssfs": "2"
	},
	"10": {
		"frame_rate": "0",
		"bit_rate": "1",
		"resolution": "3",
		"boot": "0",
		"ssfs": "2"
	},
	"20": {
		"frame_rate": "0",
		"bit_rate": "1",
		"resolution": "3",
		"boot": "0",
		"ssfs": "2"
	},
	"1": [{
		"a": "b",
		"marble": "2222"
	}, {
		"Tom": "23"
	}, {
		"Tony": "4"
	}],
	"2": [{
		"a": "b",
		"marble": "2222"
	}, {
		"Tom": "23"
	}, {
		"Tony": "4"
	}],
	"object": {
		"a": "b",
		"c": "d",
		"e": "f"
	}
}
较复杂的Json读取
void Read_json()
{
	ifstream ifstrema("config_json.json", std::ios_base::in);

	ptree node;
	read_json(ifstrema, node);

	int intVersion = node.get<int>("version");
	
	// 迭代获取对象
	ptree temp = node.get_child("0");
	
	for (boost::property_tree::ptree::iterator it = temp.begin(); it != temp.end(); ++it)
	{
		cout << "first:" << it->first << endl;
		cout << "second:" << it->second.data() << endl;
	}

	ptree objNode = node.get_child("object");
	

	for (boost::property_tree::ptree::iterator it = objNode.begin(); it != objNode.end(); ++it)
	{
		cout << "object fist:  " << it->first << endl;
		cout << "object second: " << it->second.data() << endl;
	}

	// 获取数组对象,先获取迭代器首地址,然后按照键值对获取值
	ptree arr = node.get_child("1");
	 
	boost::property_tree::ptree::iterator it = arr.begin();

	cout << it->second.get<string>("a") << endl;
	cout << it->second.get<string>("marble") << endl;
	
	it++;  // 迭代器++,指针指向下一个数组首地址。

	cout << it->second.get<string>("Tom") << endl;

	it++;
}

运行结果
Boost学习之读写json

写在结尾

以上是boost读取json文件的步骤和注意点,刚接触boost,较多的语法知识等还在熟悉中,如果本文中有错误,请随时联系博主进行修改;如果对你有帮助,请点赞支持,谢谢。

相关标签: Boost