CJOSN数据解析操作

        JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,常用于在客户端和服务器之间传输数据。由于它是一种文本格式,易于阅读和编写,并且可以在各种编程语言之间进行解析和生成数据,因此它成为了一种普遍的数据交换格式。

1.JSON基础

        JSON由键值对构成,键名必须是字符串,值可以是任意有效的JSON数据类型。
数据包围在大括号 {} 中,键值对之间用逗号 , 分隔。

2.CJOSN配置

        CJSON是一个使用C语言编写的JSON数据解析器,具有超轻便,可移植,单文件的特点,使用MIT开源协议。

使用CJSON时,你需要确保将以下两个文件包含在你的项目目录中:

  • cJSON.h
  • cJSON.c

然后将 cJSON.h 编译到你的项目中,以实现JSON数据的解析和处理功能。

下载地址:https://github.com/DaveGamble/cJSON/releases

3. JSON解析方法      

        在实际应用中,可以采用以下几种常见的JSON解析方法:

  • 逐级解析:从JSON的最外层开始,逐级解析每个键值对或数组元素。
  • 递归解析:递归地处理嵌套结构,直到整个JSON文档被解析完毕。

4. 实际应用示例

        示例 1:逐级解析复杂的 JSON 数据以获取特定数据

#include <stdio.h>
#include <string.h>
#include "cJSON.h" 

int main() {
    const char *json_str = "{"
        "\"name\": \"John Doe\","
        "\"age\": 30,"
        "\"address\": {"
            "\"street\": \"123 Main St\","
            "\"city\": \"Anytown\","
            "\"state\": \"CA\","
            "\"postalCode\": \"12345\""
        "}"
    "}";

    cJSON *root = cJSON_Parse(json_str);
    if (root == NULL) {
        printf("Error parsing JSON: %s\n", cJSON_GetErrorPtr());
        return 1;
    }

    cJSON *name = cJSON_GetObjectItem(root, "name");
    if (cJSON_IsString(name) && (name->valuestring != NULL)) {
        printf("Name: %s\n", name->valuestring);
    }

    cJSON *age = cJSON_GetObjectItem(root, "age");
    if (cJSON_IsNumber(age)) {
        printf("Age: %d\n", age->valueint);
    }

    cJSON *address = cJSON_GetObjectItem(root, "address");
    if (cJSON_IsObject(address)) {
        cJSON *street = cJSON_GetObjectItem(address, "street");
        cJSON *city = cJSON_GetObjectItem(address, "city");
        cJSON *state = cJSON_GetObjectItem(address, "state");
        cJSON *postalCode = cJSON_GetObjectItem(address, "postalCode");

        if (cJSON_IsString(street) && cJSON_IsString(city) &&
            cJSON_IsString(state) && cJSON_IsString(postalCode)) {
            printf("Address: %s, %s, %s %s\n", street->valuestring, city->valuestring,
                   state->valuestring, postalCode->valuestring);
        }
    }

    cJSON_Delete(root);
    return 0;
}
        示例 2:递归形式读取所有数据
#include <stdio.h>
#include <string.h>
#include "cJSON.h" 

void print_json_recursive(cJSON *item, const char *parent_key) {
    // Check if item is an object
    if (item->type == cJSON_Object) {
        // Print each key-value pair
        cJSON *child = item->child;
        while (child != NULL) {
            // Construct key based on parent key (if available)
            char *key;
            if (parent_key != NULL) {
                key = cJSON_AddItemToObject(NULL, parent_key, cJSON_CreateString(child->string));
            } else {
                key = child->string;
            }

            // Recursively print value
            print_json_recursive(child, key);

            child = child->next;
        }
    } else if (item->type == cJSON_String) {
        // Print string value
        printf("%s: %s\n", parent_key, item->valuestring);
    } else if (item->type == cJSON_Number) {
        // Print number value
        printf("%s: %g\n", parent_key, item->valuedouble);
    } else if (item->type == cJSON_Array) {
        // Handle array (if needed)
    } else {
        // Handle other types as needed
    }
}

int main() {
    const char *json_str = "{"
        "\"name\": \"John Doe\","
        "\"age\": 30,"
        "\"address\": {"
            "\"street\": \"123 Main St\","
            "\"city\": \"Anytown\","
            "\"state\": \"CA\","
            "\"postalCode\": \"12345\""
        "}"
    "}";

    cJSON *root = cJSON_Parse(json_str);
    if (root == NULL) {
        printf("Error parsing JSON: %s\n", cJSON_GetErrorPtr());
        return 1;
    }

    // Start recursive printing from root
    print_json_recursive(root, NULL);

    cJSON_Delete(root);
    return 0;
}

5.总结:

        在实际应用中,通过cJSON库可以实现对复杂JSON数据的解析和处理,例如逐级解析或递归解析以获取特定数据。解析过程中需要注意处理数据类型的匹配和错误处理,确保程序的稳定性和可靠性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/784117.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

redis运维:sentinel模式如何查看所有从节点

1. 连接到sentinel redis-cli -h sentinel_host -p sentinel_port如&#xff1a; redis-cli -h {域名} -p 200182. 发现Redis主服务器 连接到哨兵后&#xff0c;我们可以使用SENTINEL get-master-addr-by-name命令来获取当前的Redis主服务器的地址。 SENTINEL get-master-a…

最小爬楼梯(dp)

import java.util.Scanner;public class ClimbingStairsCost {public static int minCostClimbingStairs(int[] cost) {int n cost.length; // 获取输入的 cost 数组的长度int[] dp new int[n 1]; // 创建一个用于存储每个台阶最小花费的 dp 数组dp[0] 0; dp[1] 0; // 初始…

解析java128陷阱

一、提要 在java开发时&#xff0c;由于基本类型不能调用方法&#xff0c;在某些方面很不方便&#xff0c;因此产生了包装类。我们把基本类型和对应的包装类的转换叫装箱、拆箱。 1.装箱 基本类型转成包装类对象 关键字valueOf->装箱,可以指定进制&#xff1a; Integer…

C# modbus验证

窗体 还有添加的serialPort控件串口通信 设置程序配置 namespace CRC {public static class CRC16{/// <summary>/// CRC校验&#xff0c;参数data为byte数组/// </summary>/// <param name"data">校验数据&#xff0c;字节数组</param>///…

NLP 面试八股:“Transformers / LLM 的词表应该选多大?“ 学姐这么告诉我答案

NLP 面试八股&#xff1a;“Transformers / LLM 的词表应该选多大?" 学姐这么告诉我答案 原创 看图学 看图学 2024年07月03日 07:55 北京 题目&#xff1a; Transformers/大模型的 token vocabulary 应该选多大&#xff1f; 答案 先说一下结论&#xff1a; 数据量够大…

docker 重要且常用命令大全

本文将总结一些常见的重要的docker命令&#xff0c;以作备忘。后续如果有新的比较常用重要的也会更新进来。欢迎补充。 docker服务管理 首先我们要解释一下&#xff1a;systemctl和docker命令的不同 systemctl&#xff1a;是许多 Linux 发行版中默认的初始化系统和服务管理器。…

提高LabVIEW软件通用性的方法

提高LabVIEW软件通用性的方法 在使用LabVIEW开发软件时&#xff0c;提高软件的通用性非常重要。通用性意味着软件可以在不同的应用场景中使用&#xff0c;具备高度的适应性和灵活性&#xff0c;从而提高软件的价值和用户满意度。以下从多个角度详细探讨如何提高LabVIEW软件的通…

媒体查询:根据设备特征动态调整样式和布局

不知道你会不会有一个疑问&#xff0c;同一个网站&#xff0c;用手机看和用电脑看在首选项和排版会发生一些变化&#xff0c;但我们使用起来仍然非常顺手&#xff0c;这就是响应式设计。响应式设计原理是指网页可以根据不同使用设备的屏幕尺寸&#xff0c;做出相应的调整和变化…

Linux走进网络

走进网络之网络解析 目录 走进网络之网络解析 一、认识计算机 1.计算机的发展 2.传输介质 3.客户端与服务器端的概念 交换机 路由器 二、计算机通信与协议 1. 协议的标准化 2. 数据包的传输过程 OSI 协议 ARP协议 3. TCP/IP:四层模型 4. TCP三次握手和四次挥手…

OceanBase 配置项系统变量实现及应用详解(1):配置项的定义及使用方法

《OceanBase 配置项&系统变量实现及应用详解》专题导读 在使用OceanBase的过程中&#xff0c;看到大家经常会遇到“参数”、“配置项”、“系统变量”等概念&#xff0c;却不太清楚它们是不是同一个东西&#xff0c;以及应该如何使用。一些对数据库开发感兴趣的朋友&#…

LabVIEW开发商业软件的多角度分析与注意事项

在使用LabVIEW开发商业软件时&#xff0c;有许多方面需要考虑和注意&#xff0c;包括项目管理、架构设计、性能优化、用户体验、安全性、维护与支持等。以下是从多个角度详细分析在LabVIEW中开发商业软件需要注意的事项。 项目管理 需求分析&#xff1a;确保深入了解客户需求&a…

虚值期权和实值期权的区别?便宜的虚值期权是最好的选择吗?

今天带你了解虚值期权和实值期权的区别&#xff1f;便宜的虚值期权是最好的选择吗&#xff1f;买实值期权和买虚值期权都有各自的优势和风险。实值期权是指行权价格低于标的资产的市场价格&#xff0c;而虚值期权则是指行权价格高于标的资产的市场价格。 实值期权和虚值期权的…

SAPUI5基础知识11 - 组件配置(Component)

1. 背景 组件&#xff08;Component&#xff09;是SAPUI5应用程序中独立且可重用的部件。 SAPUI5提供以下两类组件: faceless组件 (class: sap.ui.core.Component): 无界面组件即没有用户界面相关的元素&#xff0c;用于不需要UI元素编码的场景&#xff1b; UI组件 (class: …

Greenplum(二)【SQL】

前言 Greenplum 的剩余部分主要其实主要就是 DDL 和之前学的 MySQL 不大一样&#xff0c;毕竟 Greenplum 是基于 PostgreSQL 数据库的&#xff0c;不过那些 DML 和 MySQL、Hive 基本上大差不差&#xff0c;所以就没有必要浪费时间了。 1、DDL 1.1、库操作 1.1.1、创建数据库…

p11函数和递归

递归与迭代 求n的阶乘。&#xff08;不考虑溢出&#xff09; int Fac1(int n) {int i0;int ret1;for(i1;i<n;i){ret*i;}return ret; } int main(){//求n的阶乘int n0;int ret0;scanf("%d",&n);retFac1(n);printf("%d\n",ret);return 0; } int Fac…

Qt 进程间通信(一)——QSharedMemory共享内存

QSharedMemory共享内存 序言环境理论—逻辑理解实战—代码读取示例写入示例 序言 讲讲Qt的共享内存吧&#xff0c;巩固下 环境 msvc2022 Qt5.15 参考文档&#xff1a;https://doc.qt.io/qt-5/qsharedmemory.html 理论—逻辑理解 看下面前&#xff0c;你需要将共享内存看成…

【设计模式】观察者模式(定义 | 特点 | Demo入门讲解)

文章目录 定义结构Demo | 代码Subject目标类Observer抽象观察者观察者1 | CPU监听器观察者2 | 内存监听器客户端 | Client 优点适合场景 定义 所谓观察者模式就是你是被观察的那个对象&#xff0c;你爸爸妈妈就是观察者&#xff0c;一天24h盯着你&#xff0c;一旦你不听话&…

NFT 技术在艺术领域的应用

NFT (Non-Fungible Token) 技术在艺术领域有着广泛的应用&#xff0c;为艺术家和艺术品收藏家带来了新的机遇和挑战。以下是 NFT 技术在艺术领域的一些主要应用。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1. 数字艺术品确权和交…

spring mvc学习

第四章 Spring MVC 第一节 Spring MVC 简介 1. Spring MVC SpringMVC是一个Java 开源框架&#xff0c; 是Spring Framework生态中的一个独立模块&#xff0c;它基于 Spring 实现了Web MVC&#xff08;数据、业务与展现&#xff09;设计模式的请求驱动类型的轻量级Web框架&am…

C#-反射

一、概念 反射&#xff08;Reflection&#xff09;在C#中是一种非常重要的特性&#xff0c;它为开发者提供了在运行时获取和操作关于类型、成员、属性、方法等的详细信息的能力。通过反射&#xff0c;开发者可以在程序运行期间动态地创建对象、调用方法、设置属性值以及进行其…