JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。 这些特性使JSON成为理想的数据交换语言。
JSON建构于两种结构:
- “名称/值”对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。
- 值的有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)。
这些都是常见的数据结构。事实上大部分现代计算机语言都以某种形式支持它们。这使得一种数据格式在同样基于这些结构的编程语言之间交换成为可能。
JSON具有以下这些形式:
对象是一个无序的“‘名称/值’对”集合。一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号);“‘名称/值’ 对”之间使用“,”(逗号)分隔。
数组是值(value)的有序集合。一个数组以“[”(左中括号)开始,“]”(右中括号)结束。值之间使用“,”(逗号)分隔。
值(value)可以是双引号括起来的字符串(string)、数值(number)、true
、false
、 null
、对象(object)或者数组(array)。这些结构可以嵌套。
字符串(string)是由双引号包围的任意数量Unicode字符的集合,使用反斜线转义。一个字符(character)即一个单独的字符串(character string)。
字符串(string)与C或者Java的字符串非常相似。
数值(number)也与C或者Java的数值非常相似。除去未曾使用的八进制与十六进制格式。除去一些编码细节。
空白可以加入到任何符号之间。 以下描述了完整的语言。
C++要使用JSON来解析数据,一般采用jsoncpp.
网站:http://sourceforge.net/projects/jsoncpp/
下载了之后,解压,然后打开\jsoncpp-src-0.5.0\jsoncpp-src-0.5.0\makefiles\vs71
下的工程文件,进行编译链接就可以得到一个静态链接库json.lib
要用jsoncpp只需要将这个lib文件拷贝到你的工程目录下,并将jsoncpp-src-0.5.0\jsoncpp-src-0.5.0\include\json
复制到工程目录下,然后将这些头文件加到工程中去就可以了。
#include "Kernel.h"
#include <fstream>
int main()
{
char buff[1024];
vector<string>vItem;
vector<vector<string> > vStoreItem; //二维数组
map<string, uint32_t>m_item;
Json::Value storeItem; //最终要生成的json数据
Json::FastWriter writer;
int i = 0, j = 0;
ifstream infile("/data/release/lh/battle/conf/storeItemShielding.cnf"); //读取csv格式文件中数据
Json::Value equips;
if(!FileToJson::fileToJson("/data/release/lh/battle/conf/equips.cnf", equips)) //自己实现的一个类接口,内容大概是将文件中的json数据读入内存中,然后通过Json::Reader将其转换成Json::Value格式
{
std::cout <<"file to json failed"<<std::endl;
return false;
}
int size = equips.size();
for(i = 0; i < size; i++)
{
m_item[equips[i]["name"].asString()] = equips[i]["id"].asUInt(); //m_item是一个name与id的映射,注意格式
}
while(!infile.eof() && infile.good())
{
memset(buff, 0x00, sizeof(buff));
infile.getline(buff, sizeof(buff) - 1);
String::Split(buff, ',', vItem);
vStoreItem.push_back(vItem);
vItem.clear();
}
Json::Value storeAllItem;
if(!FileToJson::fileToJson("/data/release/lh/battle/conf/store.cnf", storeAllItem))//要被删除数据的json文件
{
std::cout <<"file to json failed" <<std::endl;
return false;
}
int count = storeAllItem.size();
for(i = 0; i < count; ++i){
Json::Value items = storeAllItem[i]["items"];
int c = items.size();
storeItem[i]["name"] = storeAllItem[i]["name"];
storeItem[i]["dynamicAdd"] = storeAllItem[i]["dynamicAdd"];
storeItem[i]["hasShowWind"] = storeAllItem[i]["hasShowWind"];
storeItem[i]["labelId"] = storeAllItem[i]["labelId"];
storeItem[i]["totalBuyLimit"] = storeAllItem[i]["totalBuyLimit"];
storeItem[i]["desc"] = storeAllItem[i]["desc"];
int temp = j = 0;
int iCount = 0;
for( ; j < c && temp < c; ++j)
{
while(items[temp]["item"].asUInt() == m_item[vStoreItem[iCount][i]] || (vStoreItem[iCount][i] == "" && iCount < 35))
{
if(temp >= c)
break;
if(vStoreItem[iCount][i] == "")
++iCount;
else
{
++temp;
++iCount;
}
}
if(temp >= c)
break;
storeItem[i]["items"][j]["quality"] = items[temp]["quality"];
storeItem[i]["items"][j]["item"] = items[temp]["item"];
storeItem[i]["items"][j]["strong"] = items[temp]["strong"];
storeItem[i]["items"][j]["remainCount"] = items[temp]["remainCount"];
storeItem[i]["items"][j]["id"] = items[temp]["id"];
storeItem[i]["items"][j]["price"] = items[temp]["price"];
storeItem[i]["items"][j]["singleBuyLimit"] = items[temp]["singleBuyLimit"];
++temp;
}
}
string storeText = writer.write(storeItem);
ofstream ofile("/data/release/lh/battle/conf/storeItemShielding.json");
ofile.write(storeText.c_str(), storeText.length());
ofile.close();
return 0;
}
库:Jsoncpp,使用时包含json.h文件就可以了。
代码详解:
1.Json库中有基本3大类,Json::Value, Json::Writer, Jons::Reader, 其中Json::Value是最基本的类,既可以代表一个对象,也可以代表一个数组。Json::Writer是Json中用于将Json::Value装换成string格式,其实json数据本身就是一个string格式,但是有一些规则需要去遵守,所以如果要将json格式写到文件中时就需要writer转换格式,其实Json::Writer是一个抽象类,所以不能被实体化,有几个继承类,其中常用的一个就是Json::FastWriter,看字面意思就知道是快写。Json::Reader用于将string格式转换成json数据,是通过函数parse(const string &, Json::Value &)实现的。
2.本程序是将一个Json文件中的某些数据删除,要被删除的数据属性都存放在一个exel表格中,这里有个技巧就是将exel表格文件转换成csv格式文件,这样能方便读取表格中的那些数据,要通过另一个Json文件读取数据属性的id,然后再通过这些id将要被删除的Json文件中将这些数据删除,注意,这里需要将csv格式通过ultraEdit转换格式为utf-8。
3.关于json文件的解析,主要有两种方法,一种是通过Json::Value::Members 类实现,Members在json中的定义为一个vector<string>类,所以可以通过迭代器来遍历,即
Json::Value::Members::iterator,然后通过函数getMemName()获取键值对。另一种方法是通过for循环,需要注意的是通过Json::Value key_value[i]方式实现解析的话需要注意格式,因为key_value中的数据类型都是特定格式的string类型,所以要调用如asUInt,asInt,asString等函数转换格式。