【问题标题】:How to transform several JSON objects using json-c?如何使用 json-c 转换几个 JSON 对象?
【发布时间】:2020-04-09 09:52:28
【问题描述】:

我希望使用 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如果对象数量太大的话会出问题,那么有没有办法让buffer一个接一个地去取对象呢?
  3. 感觉内存的释放不对,是不是忘记了一些free

【问题讨论】:

    标签: c json json-c


    【解决方案1】:

    json_tokener_parse() 返回它在提供的缓冲区中找到的第一个 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 
    )
    

    在哪里

    参数

    tok 一个 json_tokener,之前分配有 json_tokener_new()

    str 具有任何有效 JSON 表达式或其一部分的字符串。这不需要以 null 终止。

    lenstr的长度

    它基本上会像json_tokener_parse() 那样解析输入缓冲区,但在内部使用token 将能够在需要解析更多内容时提醒您。这是通过返回 json_tokener_continue 来完成的。

    请参阅文档以获取更多信息。我只是在这里引用上面提供的文档链接中显示的示例:

    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(),并打印用json_object_object_get_ex()解析的数据
    5. 重复点 (2) 直到到达文件末尾
    6. fclose()文件

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 2018-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多