我正在尝试读取JSON文件。到目前为止,我一直专注于使用 jsoncpp
图书馆。但是,我很难理解文档。任何人都可以用非专业术语解释它的作用吗?
说我有一个 people.json
看起来像这样:
{"Anna" : {
"age": 18,
"profession": "student"},
"Ben" : {
"age" : "nineteen",
"profession": "mechanic"}
}
当我读到这个时会发生什么?我可以创建某种数据结构吗? people
我可以索引 Anna
和 Ben
以及 age
和 profession
?什么是数据类型 people
?我认为它会类似于(嵌套)地图,但地图值总是必须具有相同的类型,不是吗?
我之前使用过python,而我的“目标”(可能是C ++的错误设置)是获得等效的嵌套python字典。
是的,您可以创建嵌套数据结构 people
可以索引的索引 Anna
和 Ben
。但是,您无法直接将其编入索引 age
和 profession
(我将在代码中介绍这一部分)。
数据类型 people
是类型 Json::Value
(在jsoncpp中定义)。你是对的,它类似于嵌套的地图,但是 Value
是一种数据结构,其被定义为可以存储和访问多种类型。它类似于带有的地图 string
作为关键和 Json::Value
作为价值。它也可以是一个地图 unsigned int
作为关键和 Json::Value
作为值(在json数组的情况下)。
这是代码:
#include <json/value.h>
#include <fstream>
std::ifstream people_file("people.json", std::ifstream::binary);
people_file >> people;
cout<<people; //This will print the entire json object.
//The following lines will let you access the indexed objects.
cout<<people["Anna"]; //Prints the value for "Anna"
cout<<people["ben"]; //Prints the value for "Ben"
cout<<people["Anna"]["profession"]; //Prints the value corresponding to "profession" in the json for "Anna"
cout<<people["profession"]; //NULL! There is no element with key "profession". Hence a new empty element will be created.
如您所见,您只能根据输入数据的层次结构索引json对象。
看着 这个。我找到了使用json格式最方便的方法。
它的设计就像一个STL容器,它的使用非常直观。
本质上,javascript和C ++在两个不同的原则上工作。 Javascript创建一个“关联数组”或哈希表,它将字符串键(字段名称)与值匹配。 C ++在内存中布局结构,所以前4个字节是一个整数,这是一个年龄,然后我们可能有一个固定的32字节字符串代表“职业”。
因此,javascript将处理“年龄”在一个记录中为18而在另一个记录中为“十九”的事情。 C ++不能。 (但是C ++要快得多)。
因此,如果我们想在C ++中处理JSON,我们必须从头开始构建关联数组。然后我们必须用它们的类型标记值。它是一个整数,一个实数值(可能返回为“double”),boolean,一个字符串?因此,JSON C ++类是相当大的代码块。实际上我们正在做的是在C ++中实现一些javascript引擎。然后,我们将JSON解析器作为字符串传递给JSON,并对其进行标记,并为我们提供从C ++查询JSON的函数。
用于读取json配置文件的示例(包含完整的源代码):
https://github.com/sksodhi/CodeNuggets/tree/master/json/config_read
> pwd
/root/CodeNuggets/json/config_read
> ls
Makefile README.md ReadJsonCfg.cpp cfg.json
> cat cfg.json
{
"Note" : "This is a cofiguration file",
"Config" : {
"server-ip" : "10.10.10.20",
"server-port" : "5555",
"buffer-length" : 5000
}
}
> cat ReadJsonCfg.cpp
#include <iostream>
#include <json/value.h>
#include <jsoncpp/json/json.h>
#include <fstream>
void
displayCfg(const Json::Value &cfg_root);
int
main()
{
Json::Reader reader;
Json::Value cfg_root;
std::ifstream cfgfile("cfg.json");
cfgfile >> cfg_root;
std::cout << "______ cfg_root : start ______" << std::endl;
std::cout << cfg_root << std::endl;
std::cout << "______ cfg_root : end ________" << std::endl;
displayCfg(cfg_root);
}
void
displayCfg(const Json::Value &cfg_root)
{
std::string serverIP = cfg_root["Config"]["server-ip"].asString();
std::string serverPort = cfg_root["Config"]["server-port"].asString();
unsigned int bufferLen = cfg_root["Config"]["buffer-length"].asUInt();
std::cout << "______ Configuration ______" << std::endl;
std::cout << "server-ip :" << serverIP << std::endl;
std::cout << "server-port :" << serverPort << std::endl;
std::cout << "buffer-length :" << bufferLen<< std::endl;
}
> cat Makefile
CXX = g++
PROG = readjsoncfg
CXXFLAGS += -g -O0 -std=c++11
CPPFLAGS += \
-I. \
-I/usr/include/jsoncpp
LDLIBS = \
-ljsoncpp
LDFLAGS += -L/usr/local/lib $(LDLIBS)
all: $(PROG)
@echo $(PROG) compilation success!
SRCS = \
ReadJsonCfg.cpp
OBJS=$(subst .cc,.o, $(subst .cpp,.o, $(SRCS)))
$(PROG): $(OBJS)
$(CXX) $^ $(LDFLAGS) -o $@
clean:
rm -f $(OBJS) $(PROG) ./.depend
depend: .depend
.depend: $(SRCS)
rm -f ./.depend
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -MM $^ > ./.depend;
include .depend
> make
Makefile:43: .depend: No such file or directory
rm -f ./.depend
g++ -g -O0 -std=c++11 -I. -I/usr/include/jsoncpp -MM ReadJsonCfg.cpp > ./.depend;
g++ -g -O0 -std=c++11 -I. -I/usr/include/jsoncpp -c -o ReadJsonCfg.o ReadJsonCfg.cpp
g++ ReadJsonCfg.o -L/usr/local/lib -ljsoncpp -o readjsoncfg
readjsoncfg compilation success!
> ./readjsoncfg
______ cfg_root : start ______
{
"Config" :
{
"buffer-length" : 5000,
"server-ip" : "10.10.10.20",
"server-port" : "5555"
},
"Note" : "This is a cofiguration file"
}
______ cfg_root : end ________
______ Configuration ______
server-ip :10.10.10.20
server-port :5555
buffer-length :5000
>
存储这样的人
{"Anna" : {
"age": 18,
"profession": "student"},
"Ben" : {
"age" : "nineteen",
"profession": "mechanic"}
}
将导致问题,特别是如果不同的人有相同的名称..
而是使用这样的数组存储对象
{
"peoples":[
{
"name":"Anna",
"age": 18,
"profession": "student"
},
{
"name":"Ben",
"age" : "nineteen",
"profession": "mechanic"
}
]
}
像这样,您可以枚举对象,或通过数字索引访问对象。
记住json是存储结构,而不是动态排序器或索引器。
使用存储在json中的数据来根据需要构建索引并访问数据。