Json从入门到放弃

大耗子 2020年06月16日 127次浏览

文章链接:https://codemouse.online/archives/2020-06-16-22-08-11

Json 语法

范例:

{ 
    "name": "milo", 
    "age": 80, 
    "professional": { 
        "english": 4, 
        "putonghua": 2, 
        "computer": 3, 
    },
    "languages": ["C++", "C"], 
    "phone": { 
        "number": "18570368134", 
        "type": "home" },
    "books": [{ 
        "name": "Linux kernel development", 
        "price": 7.7 
    }, {  
        "name": "Linux server development", 
        "price": 8.0 }], 
    "vip": true, 
    "address": null 
}

JSON 语法规则

JSON 语法是 JavaScript 对象表示语法的子集。

  • 数据在名称/值对中
  • 数据由逗号分隔
  • 大括号保存对象
  • 中括号保存数组

JSON 名称/值

对 JSON 数据的书写格式是:名称/值对。
名称/值对包括字段名称(在双引号中),后面写一个冒号,然后是值。
例如:"name" : "milo

JSON 值

JSON 值可以是:

  • 数字(整数或浮点数)
  • 字符串(在双引号中)
  • 逻辑值(true 或 false)
  • 数组(在中括号中)
  • 对象(在大括号中)
  • null

JSON 对象

JSON 对象在大括号({})中书写:
对象可以包含多个名称/值对:

"phone": { 
    "number": "18570368134", 
    "type": "home" 
}

JSON 数组

JSON 数组在中括号中书写:
数组可包含多个对象:

"books": [{ 
        "name": "Linux kernel development", 
        "price": 7.7 
	}, {
        "name": "Linux server development", 
        "price": 8.0 
}]

Jsoncpp的安装与使用

jsoncpp 源码地址:https://github.com/open-source-parsers/jsoncpp

ubuntu安装

sudo apt-get install libjsoncpp-dev

引用头文件
库的头文件安装在/usr/include/jsoncpp 中,
库 API 文档默认在/usr/share/doc/libjsoncpp-dev/jsoncpp-api-html/目录下

#include "jsoncpp/json/json.h"
#include "jsoncpp/json/value.h"
#include "jsoncpp/json/writer.h"

demo1

#include <iostream> 
#include <string> 
#include "jsoncpp/json/json.h" 
#include "jsoncpp/json/value.h" 
#include "jsoncpp/json/writer.h" 
using namespace std; 
int main() { 
    cout << "Hello World!" << endl; 
    Json::Value root;
	Json::FastWriter fast; 
	root["ModuleType"] = Json::Value(1); 
	root["MOduleCode"] = Json::Value("China");
    cout<<fast.write(root)<<endl; 
    Json::Value sub; 
    sub["version"] = Json::Value("1.0"); 
    sub["city"] = Json::Value(root);
    fast.write(sub); 
    cout<<sub.toStyledString()<<endl; 
    return 0; 
}

demo2

#include <string>
#include <jsoncpp/json/json.h>
#include <iostream>
 
using namespace std;
 
void readJson() {
	std::string strValue = "{\"name\":\"json\",\"array\":[{\"cpp\":\"jsoncpp\"},{\"java\":\"jsoninjava\"},{\"php\":\"support\"}]}";
 
	Json::Reader reader;
	Json::Value value;
 
	if (reader.parse(strValue, value))
	{
		std::string out = value["name"].asString();
		std::cout << out << std::endl;
		const Json::Value arrayObj = value["array"];
		for (unsigned int i = 0; i < arrayObj.size(); i++)
		{
			if (!arrayObj[i].isMember("cpp")) 
				continue;
			out = arrayObj[i]["cpp"].asString();
			std::cout << out;
			if (i != (arrayObj.size() - 1))
				std::cout << std::endl;
		}
	}
}

void writeJson() {
 
	Json::Value root;
	Json::Value arrayObj;
	Json::Value item;
 
	item["cpp"] = "jsoncpp";
	item["java"] = "jsoninjava";
	item["php"] = "support";
	arrayObj.append(item);
 
	root["name"] = "json";
	root["array"] = arrayObj;
 
	root.toStyledString();
	std::string out = root.toStyledString();
	std::cout << out << std::endl;
}

int main(int argc, char** argv) {
	readJson();
	writeJson();
	return 0;
}

编译

g++ jsonTest1.cpp -o test -ljsoncpp

Jsoncpp 支持的值

jsoncpp 使用 Json::Value 对象来保存 JSON 串,Json::Value 对象可以表示如下数据类

型:

枚举类型说明翻译
nullValue'null' value不表示任何数据,空值
intValuesigned integer value表示有符号整数
uintValueunsigned integer value表示无符号整数
realValuedouble value表示浮点数
stringValueUTF-8 string value表示 utf8 格式的字符串
booleanValuebool value表示布尔数
arrayValuearray value (ordered list)表示数组,即 JSON 串中的[]
objectValuevalue (collection of name/value pairs)表示键值对,即 JSON 串中的{}

检测保存的数据类型

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;

基础数据类型的访问

const char* asCString() const; 
JSONCPP_STRING asString() const; 
Int asInt() const; 
UInt asUInt() const; 
Int64 asInt64() const; 
UInt64 asUInt64() const; 
LargestInt asLargestInt() const; 
LargestUInt asLargestUInt() const; 
float asFloat() const; 
double asDouble() const; 
bool asBool() const; 

cJSON的安装与编译

cJson编译安装

github 地址:https://github.com/DaveGamble/cJSON
下载

git clone https://github.com/DaveGamble/cJSON.git

参考 Readme 进行编译
可以直接使用 cJSON.h 和 cJSON.c 加入到源文件

数据结构定义

typedef struct cJSON 
{ 
	/* next/prev allow you to walk array/object chains. Alternatively, use Get 
	ArraySize/GetArrayItem/GetObjectItem */ 
	struct cJSON *next; 
	struct cJSON *prev; 
	/* An array or object item will have a child pointer pointing to a chain o 
	f the items in the array/object. */ 
	struct cJSON *child; 
	/* The type of the item, as above. */ 
	int type; 
	/* The item's string, if type==cJSON_String and type == cJSON_Raw */ 
	char *valuestring; 
	/* The item's number, if type==cJSON_Number */ 
	int valueint; 
	/* The item's number, if type==cJSON_Number */ 
	double valuedouble; 
	/* The item's name string, if this item is the child of, or is in the list 
	of subitems of an object. */ 
	char *string; 
} cJSON; 
//next、prev 用于遍历数组或对象链的前向后向链表指针;
//child 指向数组或对象的孩子 节点;
//type 是 value 的类型;
//valuestring 是字符串值;
//valueint 是整数值;
//valuedouble 是浮点数值;
//string 是 key 的名字。

重点函数

cJSON_Parse

cextern cJSON *cJSON_Parse(const char *value);

  • 作用:将一个 JSON 字符串,按照 cJSON 结构体的结构序列化整个数据包,并在堆中开辟一块内 存存储 cJSON 结构体。
  • 返回值:成功返回一个指向内存块中的 cJSON 的指针,失败返回 NULL。

cJSON_Delete

extern void cJSON_Delete(cJSON *c);

  • 作用:释放位于堆中 cJSON 结构体内存。
  • 返回值:无 注意:在使用 cJSON_Parse()获取 cJSON 指针后,若不再使用了,则需要调用 cJSON_Delete() 对其释放,否则会导致内存泄漏。

cJSON_Print

extern char *cJSON_Print(const cJSON *item);

  • 作用:将 cJSON 数据解析成 JSON 字符串,并在堆中开辟一块 char*的内存空间存储 JSON 字符 串。cJSON_PrintUnformatted()与 cJSON_Print()类似,只是打印输出不带格式,而只是一个 字符串数据。
  • 返回值:成功返回一个 char*指针该指针指向位于堆中 JSON 字符串,失败返回 NULL。
  • 注意:通过 cJSON_Print()可以将 cJSON 链表中所有的 cJSON 对象打印出来,但是需要手动去 释放对应的资源:free(char *)。

cJSON_Version

extern const char* cJSON_Version(void);

  • 作用:获取当前使用的 cJSON 库的版本号。
  • 返回值:返回一个字符串数据。

cJSON_GetArrayItem

extern cJSON *cJSON_GetArrayItem(const cJSON *array, int item);

  • 作用:从 object 的 cJSON 链中寻找 key 为 string 的 cJSON 对象。
  • 返回值:成功返回一个指向 cJSON 类型的结构体指针,失败返回 NULL。

与 cJSON_GetObjectItem()类似的接口还有:

extern int cJSON_GetArraySize(const cJSON *array); 
extern cJSON *cJSON_GetObjectItem(const cJSON *object, const char *string) ;
extern int cJSON_HasObjectItem(const cJSON *object, const char *string);

所有函数

cJSON API说明
cJSON_Version()获得 cJSON 的版本
cJSON_InitHooks();初始化 cJSON_Hooks 结构体
cJSON_Parse();将字符串解析成 cJSON 结构体
cJSON_ParseWithOpts()使用一些配置解析字符串
cJSON_Print()将 cJSON 结构体转换成格式化的字符串
cJSON_PrintUnformatted()将 cJSON 结构体转换成未格式化的字符串
cJSON_PrintBuffered()将 cJSON 结构体使用 buffer 的字符串,格式化可选
cJSON_PrintPreallocated()将 cJSON 结构体使用预分配的内存的字符串,格式化可选
cJSON_Delete()删除 cJSON 结构体
cJSON_GetArraySize()返回 Array 类型的大小,对 Object 类型也是有效的
cJSON_GetArrayItem()返回 Array 类型的 index 的值,对 Object类型也有效
cJSON_GetObjectItem()使用 key 获得对应的 value
cJSON_GetObjectItemCaseSensitive()使用对大小写敏感的 key 获得对应的 value
cJSON_HasObjectItem()判断是否 ObjectItem 存在
cJSON_GetErrorPtr()获得错误信息
cJSON_IsInvalid()类型判断
cJSON_IsFalse()类型判断
cJSON_IsTrue()类型判断
cJSON_IsBool()类型判断
cJSON_IsNull()类型判断
cJSON_IsNumber()类型判断
cJSON_IsString()类型判断
cJSON_IsArray()类型判断
cJSON_IsObject()类型判断
cJSON_IsRaw()类型判断
cJSON_CreateNull()创造对应类型的 cJSON
cJSON_CreateTrue()创造对应类型的 cJSON
cJSON_CreateFalse()创造对应类型的 cJSON
cJSON_CreateBool()创造对应类型的 cJSON
cJSON_CreateNumber()创造对应类型的 cJSON
cJSON_CreateString()创造对应类型的 cJSON
cJSON_CreateRaw()创造对应类型的 cJSON
cJSON_CreateArray()创造对应类型的 cJSON
cJSON_CreateObject()创造对应类型的 cJSON
cJSON_CreateIntArray()批量创造对应类型的 cJSON
cJSON_CreateFloatArray()批量创造对应类型的 cJSON
cJSON_CreateDoubleArray()批量创造对应类型的 cJSON
cJSON_CreateStringArray()批量创造对应类型的 cJSON
cJSON_AddItemToArray()在指定 Array 后面增加 Item
cJSON_AddItemToObject()在指定 Object 后面增加 Item
cJSON_AddItemToObjectCS()在指定 Object 后面增加 const Item
cJSON_AddItemReferenceToArray()在指定 Array 后面增加 Item 引用
cJSON_DetachItemViaPointer()通过指针从 Array 删除 Item 的引用
cJSON_DetachItemFromArray()从 Array 删除 Item 的引用
cJSON_DeleteItemFromArray()从 Array 删除 Item
cJSON_DetachItemFromObject()从 Object 删除 Item 的引用
cJSON_DetachItemFromObjectCaseSensitive()大小写敏感的从 Object 删除 Item 的引用
cJSON_DeleteItemFromObject()从 Object 删除 Item
cJSON_DeleteItemFromObjectCaseSensitive()大小写敏感的从 Object 删除 Item
cJSON_InsertItemInArray()在 Array 指定位置插入 Item
cJSON_ReplaceItemViaPointer()使用指针替代 Item
cJSON_ReplaceItemInArray()替换 Array 的 Item
cJSON_ReplaceItemInObject()替换 Object 的 Item
cJSON_ReplaceItemInObjectCaseSensitive()大小写敏感的替换 Object 的 Item
cJSON_Duplicate()复制 cJSON 结构体
cJSON_Compare()比较两个 cJSON 结构体
cJSON_Minify()将格式化的字符串压缩
cJSON_AddNullToObject()调用 cJSON_AddItemToObject 和 cJSON_CreateNull
cJSON_AddTrueToObject()调用 cJSON_AddItemToObject 和 cJSON_CreateTrue
cJSON_AddFalseToObject()调用 cJSON_AddItemToObject 和 cJSON_CreateFalse
cJSON_AddBoolToObject()调用 cJSON_AddItemToObject 和 cJSON_CreateBool
cJSON_AddNumberToObject()调用 cJSON_AddItemToObject 和 cJSON_CreateNumber
cJSON_AddStringToObject()调用 cJSON_AddItemToObject 和 cJSON_CreateString
cJSON_AddRawToObject()调用 cJSON_AddItemToObject 和 cJSON_CreateRaw
cJSON_SetIntValue()设置 int 的值,同时也设置 double 的值
cJSON_SetNumberValue()后台会调用 cJSON_SetNumberHelper
cJSON_SetNumberHelper()设置 cJSON 的 number 类型的值
cJSON_malloc()cJSON 的 malloc 函数,调用 malloc 函数
cJSON_free()cJSON 的 free 函数,调用 free 函数

demo