如何使用 json-c 转换多个 JSON 对象?
How to transform several JSON objects using json-c?
我希望使用 json-c 库来转换我的 .json 文档中包含的所有对象:
{
"name": "mathieu",
"password": "def118e47a2f36b73805b01a5fa3f73b506b98166a929802338db6868e28d942",
"salt": "nXvtCQEqx8l1uNheIJLoO8VI7049vgIS",
"email": "mathieu@mail.com"
}
{
"name": "cesar",
"password": "487b36f3e5a3a74ec3bf2bf48cbc49cde249b08977d22394122c9d512d0e94b4",
"salt": "Q3QnWFZnLXg8217V1uLaBka6R3CZvCfl",
"email": "cesar@mail.com"
}
为了转换它们(目前我只想显示),我使用了以下代码(我遵循了 Youtube video 中的说明):
#include <stdio.h>
#include <stdlib.h>
#include <json-c/json.h>
//#include "../../include/personnes.h"
//int parseMyJsonPersonne(){
int main(){
FILE* fichier = NULL;
char buffer[1024];
struct json_object *parsed_json;
struct json_object *name;
struct json_object *password;
struct json_object *salt;
struct json_object *email;
fichier = fopen("../../data/Personne.json", "r");
if (fichier != NULL) {
fread(buffer, 1024, 1, fichier);
}
else {
printf("Une ERREUR est survenue lors du chargement des différents comptes\n");
return 1;
}
fclose(fichier);
printf("buffer : %s\n", buffer);
parsed_json = json_tokener_parse(buffer);
json_object_object_get_ex(parsed_json, "name", &name);
json_object_object_get_ex(parsed_json, "password", &password);
json_object_object_get_ex(parsed_json, "salt", &salt);
json_object_object_get_ex(parsed_json, "email", &email);
printf("name : %s\n", json_object_get_string(name));
printf("password : %s\n", json_object_get_string(password));
printf("salt : %s\n", json_object_get_string(salt));
printf("email : %s\n", json_object_get_string(email));
json_object_object_get_ex(parsed_json, "name", &name);
printf("name 2 : %s\n", json_object_get_string(name));
free(name);
free(password);
free(salt);
free(email);
return 0;
}
这是终端在编译和执行后显示给我的内容:
buffer : {
"name": "mathieu",
"password": "def118e47a2f36b73805b01a5fa3f73b506b98166a929802338db6868e28d942",
"salt": "nXvtCQEqx8l1uNheIJLoO8VI7049vgIS",
"email": "mathieu@mail.com"
}
{
"name": "cesar",
"password": "487b36f3e5a3a74ec3bf2bf48cbc49cde249b08977d22394122c9d512d0e94b4",
"salt": "Q3QnWFZnLXg8217V1uLaBka6R3CZvCfl",
"email": "cesar@mail.com"
}
name : mathieu
password : def118e47a2f36b73805b01a5fa3f73b506b98166a929802338db6868e28d942
salt : nXvtCQEqx8l1uNheIJLoO8VI7049vgIS
email : mathieu@mail.com
name 2 : mathieu
所以这是我的各种问题 :
- 我怎样才能转到下一个对象并知道我的 .json 中对象的数量?
- 我觉得把buffer初始化成1024如果object的数量太多会出问题,有没有办法让buffer一个一个的取object?
- 感觉内存释放不对,是不是忘记了一些free?
json_tokener_parse()
returns 它在提供的缓冲区中找到的第一个 JSON 对象。当你调用它时,你将它放在一个名为 parsed_json
.
的变量中
自从您第二次尝试获取您不断传递的名称后 parsed_json
,
json_object_object_get_ex(parsed_json, "name", &name);
printf("name 2 : %s\n", json_object_get_string(name));
检索到相同的名称。
您需要做的是通过调用json_tokener_parse_ex
继续解析。根据documentation,它的界面是
JSON_EXPORT struct json_object* json_tokener_parse_ex(
struct json_tokener * tok,
const char * str,
int len
)
哪里
Parameters
tok a json_tokener previously allocated with json_tokener_new()
str a string with any valid JSON expression, or portion of. This does not need to be null terminated.
len the length of str
它基本上会像 json_tokener_parse()
一样解析输入缓冲区,但在内部使用 令牌 将能够在需要解析更多内容时提醒您。这是通过返回 json_tokener_continue
.
来完成的
请参阅文档以获得更多信息。我只是在这里引用上面提供的文档 link 中显示的示例:
json_object *jobj = NULL;
const char *mystring = NULL;
int stringlen = 0;
enum json_tokener_error jerr;
do
{
mystring = ... // get JSON string, e.g. read from file, etc...
stringlen = strlen(mystring);
jobj = json_tokener_parse_ex(tok, mystring, stringlen);
} while ((jerr = json_tokener_get_error(tok)) == json_tokener_continue);
if (jerr != json_tokener_success)
{
fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
// Handle errors, as appropriate for your application.
}
if (tok->char_offset < stringlen) // XXX shouldn't access internal fields
{
// Handle extra characters after parsed object as desired.
// e.g. issue an error, parse another object from that point, etc...
}
// Success, use jobj here.
另一种解决方案
至于其他问题,我确认如果 JSON 对象的数量不断增加,您的缓冲区将首先或稍后出现问题。处理这个问题会导致另一种解决方案。
当然您可以一个一个地阅读它们,但是您必须在从文件读取时自己执行一些解析。但是,如果您确定文件结构 始终 是您在问题中发布的那个,那么您很幸运:您可以做的是
fopen()
文件,像现在一样
- 使用
fgets()
而不是 fread()
逐行读取文件。将数据放入 buffer
- 检查最后一行是否包含右花括号
}
。如果是,继续
- 现在
buffer
只包含一个对象。像之前一样调用 json_tokener_parse()
,并打印使用 [=27=] 解析的数据
- 重复指向 (2) 直到到达文件末尾
fclose()
文件
我希望使用 json-c 库来转换我的 .json 文档中包含的所有对象:
{
"name": "mathieu",
"password": "def118e47a2f36b73805b01a5fa3f73b506b98166a929802338db6868e28d942",
"salt": "nXvtCQEqx8l1uNheIJLoO8VI7049vgIS",
"email": "mathieu@mail.com"
}
{
"name": "cesar",
"password": "487b36f3e5a3a74ec3bf2bf48cbc49cde249b08977d22394122c9d512d0e94b4",
"salt": "Q3QnWFZnLXg8217V1uLaBka6R3CZvCfl",
"email": "cesar@mail.com"
}
为了转换它们(目前我只想显示),我使用了以下代码(我遵循了 Youtube video 中的说明):
#include <stdio.h>
#include <stdlib.h>
#include <json-c/json.h>
//#include "../../include/personnes.h"
//int parseMyJsonPersonne(){
int main(){
FILE* fichier = NULL;
char buffer[1024];
struct json_object *parsed_json;
struct json_object *name;
struct json_object *password;
struct json_object *salt;
struct json_object *email;
fichier = fopen("../../data/Personne.json", "r");
if (fichier != NULL) {
fread(buffer, 1024, 1, fichier);
}
else {
printf("Une ERREUR est survenue lors du chargement des différents comptes\n");
return 1;
}
fclose(fichier);
printf("buffer : %s\n", buffer);
parsed_json = json_tokener_parse(buffer);
json_object_object_get_ex(parsed_json, "name", &name);
json_object_object_get_ex(parsed_json, "password", &password);
json_object_object_get_ex(parsed_json, "salt", &salt);
json_object_object_get_ex(parsed_json, "email", &email);
printf("name : %s\n", json_object_get_string(name));
printf("password : %s\n", json_object_get_string(password));
printf("salt : %s\n", json_object_get_string(salt));
printf("email : %s\n", json_object_get_string(email));
json_object_object_get_ex(parsed_json, "name", &name);
printf("name 2 : %s\n", json_object_get_string(name));
free(name);
free(password);
free(salt);
free(email);
return 0;
}
这是终端在编译和执行后显示给我的内容:
buffer : {
"name": "mathieu",
"password": "def118e47a2f36b73805b01a5fa3f73b506b98166a929802338db6868e28d942",
"salt": "nXvtCQEqx8l1uNheIJLoO8VI7049vgIS",
"email": "mathieu@mail.com"
}
{
"name": "cesar",
"password": "487b36f3e5a3a74ec3bf2bf48cbc49cde249b08977d22394122c9d512d0e94b4",
"salt": "Q3QnWFZnLXg8217V1uLaBka6R3CZvCfl",
"email": "cesar@mail.com"
}
name : mathieu
password : def118e47a2f36b73805b01a5fa3f73b506b98166a929802338db6868e28d942
salt : nXvtCQEqx8l1uNheIJLoO8VI7049vgIS
email : mathieu@mail.com
name 2 : mathieu
所以这是我的各种问题 :
- 我怎样才能转到下一个对象并知道我的 .json 中对象的数量?
- 我觉得把buffer初始化成1024如果object的数量太多会出问题,有没有办法让buffer一个一个的取object?
- 感觉内存释放不对,是不是忘记了一些free?
json_tokener_parse()
returns 它在提供的缓冲区中找到的第一个 JSON 对象。当你调用它时,你将它放在一个名为 parsed_json
.
自从您第二次尝试获取您不断传递的名称后 parsed_json
,
json_object_object_get_ex(parsed_json, "name", &name);
printf("name 2 : %s\n", json_object_get_string(name));
检索到相同的名称。
您需要做的是通过调用json_tokener_parse_ex
继续解析。根据documentation,它的界面是
JSON_EXPORT struct json_object* json_tokener_parse_ex(
struct json_tokener * tok,
const char * str,
int len
)
哪里
Parameters
tok a json_tokener previously allocated with
json_tokener_new()
str a string with any valid JSON expression, or portion of. This does not need to be null terminated.
len the length of str
它基本上会像 json_tokener_parse()
一样解析输入缓冲区,但在内部使用 令牌 将能够在需要解析更多内容时提醒您。这是通过返回 json_tokener_continue
.
请参阅文档以获得更多信息。我只是在这里引用上面提供的文档 link 中显示的示例:
json_object *jobj = NULL;
const char *mystring = NULL;
int stringlen = 0;
enum json_tokener_error jerr;
do
{
mystring = ... // get JSON string, e.g. read from file, etc...
stringlen = strlen(mystring);
jobj = json_tokener_parse_ex(tok, mystring, stringlen);
} while ((jerr = json_tokener_get_error(tok)) == json_tokener_continue);
if (jerr != json_tokener_success)
{
fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
// Handle errors, as appropriate for your application.
}
if (tok->char_offset < stringlen) // XXX shouldn't access internal fields
{
// Handle extra characters after parsed object as desired.
// e.g. issue an error, parse another object from that point, etc...
}
// Success, use jobj here.
另一种解决方案
至于其他问题,我确认如果 JSON 对象的数量不断增加,您的缓冲区将首先或稍后出现问题。处理这个问题会导致另一种解决方案。
当然您可以一个一个地阅读它们,但是您必须在从文件读取时自己执行一些解析。但是,如果您确定文件结构 始终 是您在问题中发布的那个,那么您很幸运:您可以做的是
fopen()
文件,像现在一样- 使用
fgets()
而不是fread()
逐行读取文件。将数据放入buffer
- 检查最后一行是否包含右花括号
}
。如果是,继续 - 现在
buffer
只包含一个对象。像之前一样调用json_tokener_parse()
,并打印使用 [=27=] 解析的数据
- 重复指向 (2) 直到到达文件末尾
fclose()
文件