如何使用 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

所以这是我的各种问题 :

  1. 我怎样才能转到下一个对象并知道我的 .json 中对象的数量?
  2. 我觉得把buffer初始化成1024如果object的数量太多会出问题,有没有办法让buffer一个一个的取object?
  3. 感觉内存释放不对,是不是忘记了一些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 对象的数量不断增加,您的缓冲区将首先或稍后出现问题。处理这个问题会导致另一种解决方案。

当然您可以一个一个地阅读它们,但是您必须在从文件读取时自己执行一些解析。但是,如果您确定文件结构 始终 是您在问题中发布的那个,那么您很幸运:您可以做的是

  1. fopen() 文件,像现在一样
  2. 使用 fgets() 而不是 fread() 逐行读取文件。将数据放入 buffer
  3. 检查最后一行是否包含右花括号}。如果是,继续
  4. 现在 buffer 只包含一个对象。像之前一样调用 json_tokener_parse() ,并打印使用 [​​=27=]
  5. 解析的数据
  6. 重复指向 (2) 直到到达文件末尾
  7. fclose() 文件