JSON:(JavaScript Object Notation)是基于Javascript的一种轻量级的数据交换格式,易于读写同时也易于机器解析和生成。具体详细有关Json的信息可参考JSON官网:http://www.json.org。
Json也是一种跨平台多语音的数据交换格式,本文仅说明Windows平台下的Json使用介绍。
Json的数据文本类似于一个MAP,数据存储中key/value对中,key和value 中间用冒号间隔,key/value数据对之间以逗号分隔,同时支持类似于C语言的数组字符串格式,用花括弧{}表示对象,中括号[]表示数组。如:
“firstName”:"Zhan" //表示Key/Value
{
"Sex":"male",
"age":18,
"name":"xiaohua"
} //标书一个对象,对象有三个属性
[
{"Sex":"male"},
{“Sex”:"female"}
]//表示一个数组
JsonCpp是一个开源的JSON序列化和序列化工具,开源代码可到github中获取https://github.com/open-source-parsers/jsoncpp.git,把代码克隆到本地。
编译方法:
1、打开文件夹下\jsoncpp\makefiles\vs71的jsoncpp.sln工程,编译该工程生成使用json必须的静态lib,lib-json.lib(名称可以修改),需要注意的是,需要将jsconcpp的工程属性中的RunTime Library 修改为Multi-threaded Debug (/MTd),将生成的lib文件拷贝到你的工厂目录中去
2、Json提供了一个整合的方法不必把所有源码都包含到你的项目中,仅通过链接一个Jsoncpp的lib文件,包含两个个头文件,和一个cpp到项目中即可方便的使用JSON的功能。
编译环境要求你的PC中安装了Python,在Json的根目录下运行 python amalgamate.py,运行该脚本会在根目录中生产一个dist目录,该目录包含了使用JSON的两个头文件json.h json-forwards.h jsoncpp.cpp三个文件,将dist目录拷贝到你的工程目录环境中。
(当然你也可以将JSONCPP的源码一起加入到你的工程中,跟你的代码一起编译)
通过以上两步你就可以任性的使用JSON这种轻量级的数据传输格式传输你想要的数据了。
Json 使用实例:
JSON使用过程中最重要的几个对象时Json::Value 代码JSON的一个对象,Json::Reader JSon的序列化对象,Json::Writer JSON的反序列化对象,通过使用以上三个对象和对象的成员方法你基本可以完成json提供的一些功能了,本文列出了三个小例子,仅供参考,更多详细内容请参阅JSON的参考文档
1、从字符串中解析JSON
void ParseJsonFromStr() { const char* str = "{\"name\":\"xiaoming\",\"age\":18}"; Json::Value root; Json::Reader reader; if (!reader.parse(str,root)) { cout << "Parse from str Failed\n"; return; } string name = root["name"].asCString(); int age = root["age"].asInt(); std::cout << "name: " << name << " age:" << age; return; }
2、从JSON文件中解析Json
void ParseJsonFromFile() { ifstream ifs; Json::Reader reader; Json::Value root; ifs.open("testReader.json",std::ios::binary); reader.parse(ifs,root,false); string schoolName = root["school"].asCString(); std::cout << "school: " << schoolName << endl; int len = root["student"].size(); Json::Value stu = root["student"]; for(int i = 0; i < len; i++) { cout << "name: "<<stu[i]["name"].asCString() << endl; cout << "age: " << stu[i]["age"].asInt() << endl; cout << "nianji: " << stu[i]["nianji"].asCString() << endl; Json::Value book = root["student"][i]["books"]; int size = book.size(); for (int j = 0; j < size; j++) { cout << "shuming: " << book[j]["shuming"].asCString() << endl; cout << "author: " << book[j]["author"].asCString() << endl; cout << "price: " << book[j]["price"].asFloat() << endl; } } return; }
3、向文件中插入Json
void InsertJsonIntoFile() { Json::FastWriter writer; Json::Reader reader; ifstream ifs; ofstream ofs; ifs.open("testReader.json",ios_base::binary); if (!ifs.is_open()) return; Json::Value root; if (reader.parse(ifs,false)) { Json::Value insertObj; Json::Value insertObj1; Json::Value arrayObj; insertObj["sex"] = "male"; insertObj1["contry"] = "china"; arrayObj.append(insertObj); arrayObj.append(insertObj1); for (int i = 0; i < root["student"].size(); i++) { root["student"][i]["sex"] = "male"; //直接在文本中插入一个字段 root["student"][i]["contry"]= "china"; root["student"][i]["info"] = arrayObj; } string str = root.toStyledString(); string strWrite = writer.write(root); ofs.open("testWroter.json"); if (!ofs.is_open()) return; ofs << strWrite; ofs.close(); } ifs.close(); }
测试代码:
#include <fstream> #include <iostream> #include "../dist/json/json.h" #include "../dist/json/json-forwards.h" #pragma comment(lib,"lib_json.lib") using namespace std; void ParseJsonFromStr(); void ParseJsonFromFile(); void InsertJsonIntoFile(); int main() { // ParseJsonFromStr();/*1、从字符串解析json*/ // ParseJsonFromFile();//从文件中解析json InsertJsonIntoFile(); //想文件中插入Json return 1; } void ParseJsonFromStr() { const char* str = "{\"name\":\"xiaoming\",root)) { cout << "Parse from str Failed\n"; return; } string name = root["name"].asCString(); int age = root["age"].asInt(); std::cout << "name: " << name << " age:" << age; return; } void ParseJsonFromFile() { ifstream ifs; Json::Reader reader; Json::Value root; ifs.open("testReader.json",false); string schoolName = root["school"].asCString(); std::cout << "school: " << schoolName << endl; int len = root["student"].size(); Json::Value stu = root["student"]; for(int i = 0; i < len; i++) { cout << "name: "<<stu[i]["name"].asCString() << endl; cout << "age: " << stu[i]["age"].asInt() << endl; cout << "nianji: " << stu[i]["nianji"].asCString() << endl; Json::Value book = root["student"][i]["books"]; int size = book.size(); for (int j = 0; j < size; j++) { cout << "shuming: " << book[j]["shuming"].asCString() << endl; cout << "author: " << book[j]["author"].asCString() << endl; cout << "price: " << book[j]["price"].asFloat() << endl; } } return; } void InsertJsonIntoFile() { Json::FastWriter writer; Json::Reader reader; ifstream ifs; ofstream ofs; ifs.open("testReader.json",false)) { Json::Value insertObj; Json::Value insertObj1; Json::Value arrayObj; insertObj["sex"] = "male"; insertObj1["contry"] = "china"; arrayObj.append(insertObj); arrayObj.append(insertObj1); for (int i = 0; i < root["student"].size(); i++) { root["student"][i]["sex"] = "male"; //直接在文本中插入一个字段 root["student"][i]["contry"]= "china"; root["student"][i]["info"] = arrayObj; } string str = root.toStyledString(); string strWrite = writer.write(root); ofs.open("testWroter.json"); if (!ofs.is_open()) return; ofs << strWrite; ofs.close(); } ifs.close(); }
与另外一种数据传输格式XML相比,JSON和XML各有优缺点,相对来说个人觉得XML的可读性比较好,但用作数据传输的话JSON效率要高一点,因为JSON是纯数据格式,而XML还用用于标记数据结束和开始的标签头等信息,不同的场景应用不同,JSON在WEB方便应用较多,具体JSON和XML的区别可参考文档《JSON和XML的区别比较》。
Google最近开源了一种数据传输格式ProtoBuf,有兴趣的朋友可以去学习比较下,本人也在持续学习中。
文章最后给出了JSON解析例子的的工程源代码,以及测试过程中用到的JSON文件,工程可以用VS2013以上的版本打开。
代码下载地址:JsonCppTest