C++利用jsoncpp库实现写入和读取json文件(含中文处理)


在C++中使用跨平台的开源库JsonCpp,实现json的序列化和反序列化操作。

1 jsoncpp常用类

1.1 Json::Value

可以表示所有支持的类型:int、double、string、object、array等
节点的类型判断:isNull、isBool、isInt、isArray、isMember、isValidIndex
类型获取:type
类型转换:asInt、asString等
节点获取:get、[]
节点比较:<、<=、>、>=、==、!=
节点操作:compare、swap、removeMember、removeindex、append等函数。

1.2 Json::Reader

将文件流或字符串解析到Json::Value中,主要使用parse函数。

1.3 Json::Writer

将Json::Value转换成字符串流等,Writer类是一个纯虚类,不能直接使用。
使用 Json::Writer 的子类:
Json::FastWriter,将数据写入一行,没有格式
Json::StyledWriter,按json格式化输出,易于阅读

2 json文件

{
    "Address": "北京",
    "Date": 1998,
    "Color": [0.8, 1, 0.5],
    "classIds": [
        [0],
        [0,1]
    ],
    "regions": [
        [[420,200],[850,300],[1279,719],[640,719]],
        [[0,0],[500,0],[500,719],[0,719]]
    ],
    "Info": {
        "Class": "三年级",
        "School": "北京一中"
    },
    "Students": [
        {
            "Id": 1,
            "sex": "男",
            "ontime": true,
            "time": "2021-01-16"
        },
        {
            "Id": 2,
            "sex": "男",
            "ontime": true,
            "time": "2021-01-16"
        }
    ]
}

3 写json文件

#include"opencv2/opencv.hpp"
#include "json/json.h"
#include <fstream>
int main()
{
	std::string strFilePath = "test.json";
	Json::Value root;
	
	//string
	root["Address"] = "北京";
	
	//int
	root["Date"] = 1998;
	
	//array
	root["Color"].append(0.8);
	root["Color"].append(1.0);
	root["Color"].append(0.5);
	
	//array-array
	root["classIds"][0].append(0);
	root["classIds"][1].append(0);
	root["classIds"][1].append(1);

	//array-array-array
	std::vector<cv::Point> pts1 = { {420,200} ,{850,300},{1279,719},{640,719} };
	std::vector<cv::Point> pts2 = { {0,0} ,{500,0},{500,719},{0,719} };
	Json::Value region1, region2;
	for (auto& pt : pts1)
	{
		Json::Value jpt;
		jpt.append(pt.x);
		jpt.append(pt.y);
		region1.append(jpt);
	}
	for (auto& pt : pts2)
	{
		Json::Value jpt;
		jpt.append(pt.x);
		jpt.append(pt.y);
		region2.append(jpt);
	}
	root["regions"].append(region1);
	root["regions"].append(region2);

	//object
	root["Info"]["Class"] = "三年级";
	root["Info"]["School"] = "北京一中";

	//array-object
	for (int i = 0; i < 2; i++)
	{
		root["Students"][i]["Id"] = i + 1;
		root["Students"][i]["sex"] = "男";
		root["Students"][i]["ontime"] = true;
		root["Students"][i]["time"] = "2021-01-16";
	}

	Json::StreamWriterBuilder builder;
	//设置格式化字符串为空,默认设置为以"\t"格式化输出JSON
	//builder["indentation"] = "";//节省内存
	//JSONCPP默认编码是UTF8,与VS默认编码不一致,当输入中文时会出现乱码
	//StreamWriterBuilder提供设置默认编码的参数
	builder["emitUTF8"] = true;
	std::ofstream outFile(strFilePath);
	outFile << Json::writeString(builder, root);
	outFile.close();
	return 0;
}

在Linux系统运行时,存储的json文件中文正常显示。
在 windows系统运行时,“北京”存储为"\u5317\u4eac",读取时控制台可以正常显示中文字符。

3.1 linux存储结果

在这里插入图片描述

3.2 windows存储结果

在这里插入图片描述

3 读json文件

#include "json/json.h"
#include <fstream>
#include <Windows.h>
int main()
{
	//windows解决控制台中文乱码
	//引入Windows.h库,设置字符编码utf-8
	SetConsoleOutputCP(CP_UTF8);

	std::string strFilePath = "test.json";

	Json::Reader json_reader;
	Json::Value rootValue;

	std::ifstream infile(strFilePath.c_str(), std::ios::binary);
	if (!infile.is_open())
	{
		std::cout << "Open config json file failed!" << std::endl;
		return 0;
	}

	if (json_reader.parse(infile, rootValue))
	{
		//string
		std::string sAddress = rootValue["Address"].asString();
		std::cout << "Address = " << sAddress << std::endl;

		//int 
		int nDate = rootValue["Date"].asInt();
		std::cout << "Date = " << nDate << std::endl;

		//array
		Json::Value colorResult = rootValue["Color"];
		if (colorResult.isArray())
		{
			for (unsigned int i = 0; i < colorResult.size(); i++)
			{
				double dColor = colorResult[i].asDouble();
				std::cout << "Color = " << dColor << std::endl;
			}
		}
		//array-array
		Json::Value classIds = rootValue["classIds"];
		if (classIds.isArray()) {

			for (int i = 0; i < classIds.size(); i++)
			{
				Json::Value classId = classIds[i];//classIds中的第i个classId组合
				if (!classId.isArray())
					continue;
				std::cout << "classIds " << i << " : [ ";
				for (int j = 0; j < classId.size(); j++) {
					int id = classId[j].asInt();
					std::cout << id << ", ";
				}
				std::cout << "]" << std::endl;
			}
		}
		//array-array-array
		Json::Value regions = rootValue["regions"];
		if (regions.isArray()) {
			for (int i = 0; i < regions.size(); i++) {
				std::cout << "region " << i << " : ";
				Json::Value region = regions[i];//regions中的第i个region
				if (!region.isArray())
					continue;
				for (int j = 0; j < region.size(); j++)
				{
					Json::Value pt = region[j]; //region中的第j个点
					if (pt.isArray()) {
						int x = pt[0].asInt();
						int y = pt[1].asInt();
						std::cout << "[ " << x << ", " << y << " ],";
					}
				}
				std::cout << std::endl;
			}
		}
		//object
		std::string sSchool = rootValue["Info"]["Class"].asString();
		std::string sClass = rootValue["Info"]["School"].asString();
		std::cout << "Class = " << sClass << std::endl;
		std::cout << "School = " << sSchool << std::endl;

		// array-object
		Json::Value studentResult = rootValue["Students"];
		if (studentResult.isArray())
		{
			for (unsigned int i = 0; i < studentResult.size(); i++)
			{
				int nId = studentResult[i]["Id"].asInt();
				std::string sSex = studentResult[i]["sex"].asString();
				bool bOnTime = studentResult[i]["ontime"].asBool();
				std::string sTime = studentResult[i]["time"].asString();
				std::cout << "Student " << i << " : Id = " << nId << ", sex = " << sSex << ", bOnTime = " << bOnTime << ", Time = " << sTime << std::endl;
			}
		}
	}
	else
	{
		std::cout << "Can not parse Json file!";
	}

	infile.close();
	return 0;

在这里插入图片描述

4 读json字符串

数据在“名称/值” 对中,数据由逗号“ , ”分隔,使用斜杆来转义“ \” 字符,大括号 “{} ”保存对象。
json数据如下:

{
"name" : "测试",
"age" : "21",
"sex" : "男"
}
#include "json/json.h"
#include <fstream>
#include <Windows.h>
int main()
{
	SetConsoleOutputCP(CP_UTF8);

	Json::Reader json_reader;
	Json::Value rootValue;

    //字符串
    std::string str =
        "{\"name\":\"测试\",\"age\":21,\"sex\":\"男\"}";

    //从字符串中读取数据
    if (json_reader.parse(str, rootValue))
    {
        std::string name = rootValue["name"].asString();
        int age = rootValue["age"].asInt();
        std::string sex = rootValue["sex"].asString();
        std::cout << name + ", " << age << ", " << sex << std::endl;
    }
	return 0;

在这里插入图片描述

参考文章

vs2022控制台输出中文字符&存储中文字符
Jsoncpp用法小结 VS2019
C++利用jsoncpp库实现写入和读取json文件
C++ Builder 生成 json,Json::StreamWriterBuilder 参数详解
C++ Json中文乱码问题

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
使用Jsoncpp进行分块读取写入超大的JSON对象可以采用以下步骤: 1. 打开JSON文件,并创建Json::Value对象存储JSON数据。 ```c++ Json::Value jsonValue; std::ifstream ifs("large.json"); ifs >> jsonValue; ``` 2. 根据需要将JSON数据分割成多个块,每个块存储在一个Json::Value对象中。 ```c++ std::vector<Json::Value> jsonBlocks; int blockSize = 10000; // 块大小 int totalSize = jsonValue.size(); // JSON对象总大小 for (int i = 0; i < totalSize; i += blockSize) { int remainSize = totalSize - i; int curSize = remainSize < blockSize ? remainSize : blockSize; Json::Value curBlock(Json::arrayValue); for (int j = i; j < i + curSize; ++j) { curBlock.append(jsonValue[j]); } jsonBlocks.push_back(curBlock); } ``` 3. 将分块后的JSON数据写入文件中。 ```c++ std::ofstream ofs("large_blocks.json"); for (const auto& block : jsonBlocks) { ofs << block.toStyledString() << std::endl; } ``` 4. 读取分块后的JSON数据。 ```c++ std::vector<Json::Value> jsonBlocks; std::ifstream ifs("large_blocks.json"); std::string line; while (std::getline(ifs, line)) { Json::Value block; std::stringstream ss(line); ss >> block; jsonBlocks.push_back(block); } ``` 5. 将分块后的JSON数据合并为一个Json::Value对象。 ```c++ Json::Value jsonValue(Json::arrayValue); for (const auto& block : jsonBlocks) { for (const auto& item : block) { jsonValue.append(item); } } ``` 需要注意的是,分块读写JSON数据需要根据实际情况选择合适的块大小,不能过大或过小。同时,分块读写JSON数据会增加一定的处理复杂度,需要谨慎处理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

waf13916

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值