使用 json-c 解析 json 文件
Parse json file using json-c
我正在使用 json-c 库。我在尝试用 C 解析 json 文件时遇到两个问题。
如果我尝试按原样解析文件,我会在 json_object_object_foreach()
处遇到分段错误。
但是如果我删除 json 文件开头和结尾的方括号,它可以工作但只解析第一个对象。我想解析整个 json 文件。
这是我的代码:
int ParseJson(const char *file)
{
char *json;
int fd;
struct json_object *obj;
struct stat st;
fd = open(file, O_RDONLY);
json = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
close(fd);
obj = json_tokener_parse(json);
json_object_object_foreach(obj, key, val) {
printf("key = %s value = %s\n",key, json_object_get_string(val));
}
return 0;
}
这是我的 json 文件:
[{
"test_1": "min",
"test_2": "max",
"test_3": "val",
"test_4": "res",
"test_5": "var",
"test_6": "hal"
}, {
"fetch_1": 300.00,
"fetch_2": 100.000,
"fetch_3": 0.000000,
"fetch_4": 0.000000,
"fetch_5": 20.00
}, {
"fetch_1": 250.00,
"fetch_2": 310.000,
"fetch_3": 3.000000,
"fetch_4": 7.000000,
"fetch_5": 18.00
}, {
"fetch_1": 450.00,
"fetch_2": 678.000,
"fetch_3": 3.000000,
"fetch_4": 3.000000,
"fetch_5": 89.00
}, {
"fetch_1": 300.00,
"fetch_2": 100.000,
"fetch_3": 7.000000,
"fetch_4": 67.000000,
"fetch_5": 50.00
}, {
"fetch_1": 900.00,
"fetch_2": 800.000,
"fetch_3": 6.000000,
"fetch_4": 5.000000,
"fetch_5": 30.00
}]
你问的关于 json-c 的问题有点好笑,我不久前刚刚为了自己的目的而选择了它。无论如何,问题肯定是@Myst在评论中描述的。
我能够重现您描述的问题,运行调试器下的程序立即显示段错误发生在迭代期间,而不是解析期间。
仔细查看代码,然后根据包的命名约定,函数(实际上是宏)json_object_object_foreach()
指定用于表示 JSON 对象的对象,不是 JSON 数组。这就是名称中第二个 "object" 的意义。您不能将该宏应用于表示 JSON 数组的对象,就像您在输入中的顶级 JSON 结构是数组时尝试做的那样。因此,在确定如何检查它之前,您必须先测试您拥有的对象的类型。
您可以通过 json_object_get_type()
或 json_object_is_type()
确定您拥有的对象的类型。对于顶级数组,您可以通过 json_object_array_length()
获取数组长度,并使用普通的 for
循环遍历索引范围,通过 json_object_array_get_idx()
检索元素。我目前看不到任何更好的选择,但也许对图书馆更有经验的人会提供一个。
我正在使用 json-c 库。我在尝试用 C 解析 json 文件时遇到两个问题。
如果我尝试按原样解析文件,我会在 json_object_object_foreach()
处遇到分段错误。
但是如果我删除 json 文件开头和结尾的方括号,它可以工作但只解析第一个对象。我想解析整个 json 文件。
这是我的代码:
int ParseJson(const char *file)
{
char *json;
int fd;
struct json_object *obj;
struct stat st;
fd = open(file, O_RDONLY);
json = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
close(fd);
obj = json_tokener_parse(json);
json_object_object_foreach(obj, key, val) {
printf("key = %s value = %s\n",key, json_object_get_string(val));
}
return 0;
}
这是我的 json 文件:
[{
"test_1": "min",
"test_2": "max",
"test_3": "val",
"test_4": "res",
"test_5": "var",
"test_6": "hal"
}, {
"fetch_1": 300.00,
"fetch_2": 100.000,
"fetch_3": 0.000000,
"fetch_4": 0.000000,
"fetch_5": 20.00
}, {
"fetch_1": 250.00,
"fetch_2": 310.000,
"fetch_3": 3.000000,
"fetch_4": 7.000000,
"fetch_5": 18.00
}, {
"fetch_1": 450.00,
"fetch_2": 678.000,
"fetch_3": 3.000000,
"fetch_4": 3.000000,
"fetch_5": 89.00
}, {
"fetch_1": 300.00,
"fetch_2": 100.000,
"fetch_3": 7.000000,
"fetch_4": 67.000000,
"fetch_5": 50.00
}, {
"fetch_1": 900.00,
"fetch_2": 800.000,
"fetch_3": 6.000000,
"fetch_4": 5.000000,
"fetch_5": 30.00
}]
你问的关于 json-c 的问题有点好笑,我不久前刚刚为了自己的目的而选择了它。无论如何,问题肯定是@Myst在评论中描述的。
我能够重现您描述的问题,运行调试器下的程序立即显示段错误发生在迭代期间,而不是解析期间。
仔细查看代码,然后根据包的命名约定,函数(实际上是宏)json_object_object_foreach()
指定用于表示 JSON 对象的对象,不是 JSON 数组。这就是名称中第二个 "object" 的意义。您不能将该宏应用于表示 JSON 数组的对象,就像您在输入中的顶级 JSON 结构是数组时尝试做的那样。因此,在确定如何检查它之前,您必须先测试您拥有的对象的类型。
您可以通过 json_object_get_type()
或 json_object_is_type()
确定您拥有的对象的类型。对于顶级数组,您可以通过 json_object_array_length()
获取数组长度,并使用普通的 for
循环遍历索引范围,通过 json_object_array_get_idx()
检索元素。我目前看不到任何更好的选择,但也许对图书馆更有经验的人会提供一个。