C语言实现json文本解析

C语言实现json文本解析

背景


项目中,有时需要根据外部输入条件,进行程序的灵活切换,运用JSON文件解析,能高效的替换指令行输入,且直观易懂。

总体方法


JSON文件准备

  • JSON数据
    • test_data.json
  • 自写调度
    • json_parser.c
    • json_parser.h
  • 库调用
    • cJSON.c,下载链接:link
    • cJSON.h,下载链接:link

DEMO思路

  • 获取json文件大小,JsonGetFileSize
  • 全部读入char字符数组,JsonConfigLoader
  • 调用cJSON.c中的函数进行对象解析并输出打印,Parser

取自库调用作者的待解析的json数据文件:test_data.json

{
    "name": "Awesome 4K",
    "resolutions": [
        {
            "width": 1280,
            "height": 720
        },
        {
            "width": 1920,
            "height": 1080
        },
        {
            "width": 3840,
            "height": 2160
        }
    ]
}

注意读取第二个对象resolutions时,内部嵌套有列表需要先获取分辨率对象后,再用列表读取获取子列表项,最后再读取子列表项中的对象元素。

调用JsonPaserDemo函数,输出效果

------------------------------- 
      _  _____  ____  _   _
     | |/ ____|/ __ \| \ | |
     | | (___ | |  | |  \| |
 _   | |\___ \| |  | | \  |
| |__| |____) | |__| | |\  |
 \____/|_____/ \____/|_| \_|
-------------------------------
name is Awesome 4k
width=3840
height=2160

实现源码


文件:json_parser.h

#ifndef JSON_TEST_H
#define JSON_TEST_H

#include "cJSON.h"

#ifdef __cplusplus
extern "C" {
#endif

void JsonPaserDemo(void);

#ifdef __cplusplus
}
#endif

#endif

文件:json_parser.c

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "cJSON.h"
#include "json_parser.h"

static void JsonBanner(void)
{
    char *banner = "\
------------------------------- \n\
      _  _____  ____  _   _     \n\
     | |/ ____|/ __ \\| \\ | |  \n\
     | | (___ | |  | |  \\| |   \n\
 _   | |\\___ \\| |  | | \\  |  \n\
| |__| |____) | |__| | |\\  |   \n\
 \\____/|_____/ \\____/|_| \\_| \n\
------------------------------- \n";
    printf("%s", banner);
}

static int JsonGetFileSize(FILE *fp)
{
    fseek(fp, 0, SEEK_END);
    int fsize = ftell(fp);
    return fsize;
}

static void JsonConfigLoader(FILE *fp, char *data, int fsize)
{
    rewind(fp);
    fsize = fread(data, 1, fsize, fp);
    data[fsize] = '\0';
    return;
}

static int Parser(char *data)
{
    int ret = 0;
    cJSON *json = cJSON_Parse(data);
    if (json == NULL) {
        return -1; // json malloc failed
    }
    cJSON *node = NULL;
    cJSON *subNode = NULL;
    cJSON *tmpNode = NULL;

    node = cJSON_GetObjectItem(json, "name");
    if(strcmp(node->valuestring, "Awesome 4K") == 0){
        printf("name is Awesome 4K\n");;
    } else {
        printf("name not Awesome 4K\n");
    }

    node = cJSON_GetObjectItem(json, "resolutions");
    int resMode = 2;
    subNode = cJSON_GetArrayItem(node, resMode);
    tmpNode = cJSON_GetObjectItem(subNode, "width");
    printf("width=%d\n", tmpNode->valueint);
    tmpNode = cJSON_GetObjectItem(subNode, "height");
    printf("height=%d\n", tmpNode->valueint);

    free(json);
    return ret;
}


#define FILE_PATH "D:\\test_data.json"
void JsonPaserDemo(void)
{
    JsonBanner();

    FILE *fp = fopen(FILE_PATH, "rb");
    if (fp == NULL) {
        printf("file open failed\n");
        fclose(fp);
    }

    int fsize = JsonGetFileSize(fp);
    if (fsize < 0) {
        printf("size < 0\n");
        fclose(fp);
        return;
    }

    char *data = (char *)malloc((fsize + 1) * sizeof(char));
    if (data == NULL) {
        printf("malloc data failed\n");
        fclose(fp);
        free(data);
        data = NULL;
        return;
    }

    JsonConfigLoader(fp, data, fsize);
    int ret = Parser(data);
    if (ret != 0) {
        printf("ParserLoad failed, ret=%d\n", ret);
        fclose(fp);
        free(data);
        data = NULL;
        return;
    }
    fclose(fp);
    free(data);
    data = NULL;

    return;
}

相关资料


  1. cJSON使用说明,link
  2. figlet:ASCII 艺术字生成器,大字符大文字,link
  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值