当前位置: 首页 > article >正文

从天气预报API实战解析:手把手教你用cJSON处理嵌套数组与对象(避坑指南)

从天气预报API实战解析手把手教你用cJSON处理嵌套数组与对象避坑指南天气预报API返回的JSON数据往往结构复杂包含多层嵌套的对象和数组。对于C语言开发者来说使用轻量级的cJSON库解析这类数据时稍有不慎就会遇到空指针访问、内存泄漏等问题。本文将以一个真实的天气预报API响应为例带你逐步拆解嵌套结构的解析过程并分享几个关键避坑技巧。1. 天气预报API的数据结构分析典型的天气预报API响应包含当前天气数据和未来几天预报数组。以下是我们将要解析的JSON结构示例{ city: Beijing, update_time: 2023-05-20 14:00, forecast: [ { date: 2023-05-20, temp_max: 28, temp_min: 18, condition: sunny, humidity: 45 }, { date: 2023-05-21, temp_max: 26, temp_min: 17, condition: cloudy, humidity: 60 } ] }这种结构有三个显著特点多层嵌套最外层是城市信息forecast字段包含一个数组动态长度forecast数组长度不固定取决于预报天数混合类型包含字符串、数字等多种数据类型2. cJSON解析基础从简单对象开始在解析复杂结构前先确保掌握基本对象解析。cJSON提供了几个核心函数cJSON *root cJSON_Parse(json_string); // 解析JSON字符串 cJSON *item cJSON_GetObjectItem(root, key); // 获取对象字段 int value item-valueint; // 获取整数值 char *str item-valuestring; // 获取字符串值 cJSON_Delete(root); // 释放内存注意每次调用cJSON_Parse后必须对应调用cJSON_Delete否则会导致内存泄漏。3. 解析嵌套对象与数组的完整流程3.1 安全解析的基本模式解析任何JSON数据都应遵循以下安全模式cJSON *root cJSON_Parse(json_string); if (!root) { printf(Parse error: %s\n, cJSON_GetErrorPtr()); return; } // 解析逻辑... cJSON_Delete(root);3.2 逐层解析嵌套对象以获取城市信息为例cJSON *city_obj cJSON_GetObjectItem(root, city); if (city_obj city_obj-type cJSON_String) { printf(City: %s\n, city_obj-valuestring); } cJSON *time_obj cJSON_GetObjectItem(root, update_time); if (time_obj time_obj-type cJSON_String) { printf(Update time: %s\n, time_obj-valuestring); }3.3 遍历数组的正确方式处理forecast数组需要特别注意cJSON *forecast_array cJSON_GetObjectItem(root, forecast); if (forecast_array forecast_array-type cJSON_Array) { int array_size cJSON_GetArraySize(forecast_array); for (int i 0; i array_size; i) { cJSON *day_item cJSON_GetArrayItem(forecast_array, i); if (!day_item) continue; cJSON *date_item cJSON_GetObjectItem(day_item, date); cJSON *temp_max_item cJSON_GetObjectItem(day_item, temp_max); if (date_item date_item-type cJSON_String) { printf(Date: %s\n, date_item-valuestring); } if (temp_max_item temp_max_item-type cJSON_Number) { printf(Max temp: %d\n, temp_max_item-valueint); } } }4. 五大常见陷阱与解决方案4.1 空指针问题问题直接访问未检查的cJSON指针可能导致程序崩溃解决始终检查指针和类型// 错误示范 printf(%s\n, cJSON_GetObjectItem(root, nonexistent)-valuestring); // 正确做法 cJSON *item cJSON_GetObjectItem(root, nonexistent); if (item item-type cJSON_String) { printf(%s\n, item-valuestring); }4.2 内存泄漏问题cJSON_Print分配的内存需要手动释放解决为每个cJSON_Print调用配对freechar *json_str cJSON_Print(root); // 使用json_str... free(json_str); // 必须释放4.3 类型混淆问题错误判断字段类型导致数据错误解决严格检查type字段cJSON *item cJSON_GetObjectItem(root, temp); if (item) { if (item-type cJSON_Number) { int temp item-valueint; } else if (item-type cJSON_String) { char *temp_str item-valuestring; } }4.4 数组越界问题错误计算数组长度导致越界解决使用cJSON_GetArraySize获取准确长度int array_size cJSON_GetArraySize(array); for (int i 0; i array_size; i) { // 安全访问 }4.5 释放顺序错误问题先删除父节点导致子节点访问错误解决从内到外释放或直接删除根节点// 正确做法 cJSON_Delete(root); // 自动递归释放所有子节点 // 错误做法 cJSON_Delete(child); cJSON_Delete(parent); // 此时child已被释放导致未定义行为5. 模块化解析函数封装为提高代码复用性建议将解析逻辑封装成独立函数typedef struct { char date[20]; int temp_max; int temp_min; char condition[20]; } WeatherForecast; int parse_forecast(cJSON *root, WeatherForecast *forecasts, int max_items) { cJSON *array cJSON_GetObjectItem(root, forecast); if (!array || array-type ! cJSON_Array) return 0; int count 0; int array_size cJSON_GetArraySize(array); for (int i 0; i array_size count max_items; i) { cJSON *item cJSON_GetArrayItem(array, i); if (!item) continue; cJSON *date cJSON_GetObjectItem(item, date); cJSON *temp_max cJSON_GetObjectItem(item, temp_max); cJSON *temp_min cJSON_GetObjectItem(item, temp_min); cJSON *condition cJSON_GetObjectItem(item, condition); if (date date-type cJSON_String) { strncpy(forecasts[count].date, date-valuestring, sizeof(forecasts[count].date)-1); } if (temp_max temp_max-type cJSON_Number) { forecasts[count].temp_max temp_max-valueint; } // 其他字段处理... count; } return count; }使用示例WeatherForecast forecasts[7]; int num_forecasts parse_forecast(root, forecasts, 7); for (int i 0; i num_forecasts; i) { printf(%s: %d°C\n, forecasts[i].date, forecasts[i].temp_max); }6. 性能优化技巧处理大型JSON数据时可以考虑以下优化手段批量处理避免频繁的小内存分配预解析只解析需要的字段内存池为cJSON节点使用自定义内存管理// 示例使用内存池优化 void *pool_alloc(size_t size) { // 实现自定义内存分配 } void pool_free(void *ptr) { // 实现自定义内存释放 } // 设置cJSON内存钩子 cJSON_Hooks hooks {pool_alloc, pool_free}; cJSON_InitHooks(hooks);在实际项目中我发现最容易被忽视的是cJSON_Print生成字符串的释放问题。曾经因为忘记free这些字符串导致服务运行几天后内存耗尽崩溃。现在我会在代码审查时特别关注每个cJSON_Print是否有对应的free调用。

相关文章:

从天气预报API实战解析:手把手教你用cJSON处理嵌套数组与对象(避坑指南)

从天气预报API实战解析:手把手教你用cJSON处理嵌套数组与对象(避坑指南) 天气预报API返回的JSON数据往往结构复杂,包含多层嵌套的对象和数组。对于C语言开发者来说,使用轻量级的cJSON库解析这类数据时,稍有…...

3步打造专属游戏体验:DoL-Lyra整合包构建完全指南

3步打造专属游戏体验:DoL-Lyra整合包构建完全指南 【免费下载链接】DOL-CHS-MODS Degrees of Lewdity 整合 项目地址: https://gitcode.com/gh_mirrors/do/DOL-CHS-MODS 想要为Degrees of Lewdity游戏打造个性化的MOD组合,却苦于手动配置的繁琐&a…...

保姆级教程:在Vitis里用MicroBlaze软核读取FPGA芯片温度和电压(附完整C代码)

基于MicroBlaze与XADC的FPGA健康监测系统实战指南 在嵌入式系统开发中,实时监控FPGA芯片的工作状态是确保系统稳定运行的关键环节。Xilinx 7系列及以上FPGA内置的XADC(Xilinx Analog-to-Digital Converter)模块,配合MicroBlaze软…...

如何用League Director制作专业级《英雄联盟》高光集锦:5步完整指南

如何用League Director制作专业级《英雄联盟》高光集锦:5步完整指南 【免费下载链接】leaguedirector League Director is a tool for staging and recording videos from League of Legends replays 项目地址: https://gitcode.com/gh_mirrors/le/leaguedirector…...

USB接口技术与CMOS开关应用解析

1. USB接口技术概述:从基础到高速传输 USB(通用串行总线)技术自1996年问世以来,已经彻底改变了PC与外围设备的连接方式。作为现代数据传输的核心接口标准,USB的成功源于其简单可靠的物理连接和智能高效的协议设计。在消…...

AI模型协作:平衡生成多样性与内容质量的技术方案

1. 项目背景与核心挑战在当前的AI模型开发实践中,我们常常面临一个两难选择:追求生成结果的多样性还是确保内容质量?传统单一模型往往难以兼顾这两个目标。基础模型(Base Model)通常具备较强的创造力和多样性输出能力&…...

OnmyojiAutoScript:阴阳师自动化脚本的终极解放指南

OnmyojiAutoScript:阴阳师自动化脚本的终极解放指南 【免费下载链接】OnmyojiAutoScript Onmyoji Auto Script | 阴阳师脚本 项目地址: https://gitcode.com/gh_mirrors/on/OnmyojiAutoScript 阴阳师自动化脚本(OnmyojiAutoScript,简称…...

AO3镜像站终极访问指南:5步快速解锁全球最大同人创作平台

AO3镜像站终极访问指南:5步快速解锁全球最大同人创作平台 【免费下载链接】AO3-Mirror-Site 项目地址: https://gitcode.com/gh_mirrors/ao/AO3-Mirror-Site Archive of Our Own(AO3)作为全球最大的同人创作平台,拥有超过…...

WarcraftHelper终极指南:让魔兽争霸3在现代系统上完美运行

WarcraftHelper终极指南:让魔兽争霸3在现代系统上完美运行 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 还在为魔兽争霸3在Windows 10/1…...

从零部署:Hermes + DeepSeek V4 打造企业级智能助手(附完整代码)

引言:为什么是 Hermes DeepSeek V4? 在 2026 年的 AI 智能体(Agent)浪潮中,两个名字如雷贯耳: Hermes (爱马仕):由 Nous Research 开源的、增长最快的自进化 AI 智能体框架。它最大的特点是“…...

3步轻松搞定B站视频转文字:免费开源工具让你的学习效率提升10倍!

3步轻松搞定B站视频转文字:免费开源工具让你的学习效率提升10倍! 【免费下载链接】bili2text Bilibili视频转文字,一步到位,输入链接即可使用 项目地址: https://gitcode.com/gh_mirrors/bi/bili2text 还在为整理B站视频内…...

新手福音:借快马AI解析蓝桥杯真题,轻松入门STM32嵌入式开发

作为一名刚接触嵌入式开发的新手,面对蓝桥杯真题时常常感到无从下手。最近我发现用InsCode(快马)平台可以快速生成带详细注释的STM32项目代码,特别适合用来拆解蓝桥杯嵌入式真题的入门知识点。下面分享我的学习过程: 项目搭建与基础配置 在平…...

测试新手福音:在快马平台用AI生成你的第一份面试题学习指南

作为一名刚入行的软件测试新手,面对海量的面试题常常感到无从下手。最近我在InsCode(快马)平台尝试用AI生成了一套面试题学习应用,发现特别适合零基础入门。这里分享下我的实践心得,希望能帮到同样在准备面试的小伙伴们。 知识图谱构建学习路…...

OpenSpeedy:开源免费的终极游戏加速解决方案,3分钟上手指南

OpenSpeedy:开源免费的终极游戏加速解决方案,3分钟上手指南 【免费下载链接】OpenSpeedy 🎮 An open-source game speed modifier. 项目地址: https://gitcode.com/gh_mirrors/op/OpenSpeedy 你是否曾在单机游戏中因为缓慢的动画和冗长…...

BabelDOC:智能PDF双语翻译的终极解决方案,让学术文档翻译变得简单高效

BabelDOC:智能PDF双语翻译的终极解决方案,让学术文档翻译变得简单高效 【免费下载链接】BabelDOC Yet Another Document Translator 项目地址: https://gitcode.com/GitHub_Trending/ba/BabelDOC 在全球化时代,研究人员、学生和专业人…...

简单三步实现百度网盘免客户端高速下载:完整指南

简单三步实现百度网盘免客户端高速下载:完整指南 【免费下载链接】baidu-wangpan-parse 获取百度网盘分享文件的下载地址 项目地址: https://gitcode.com/gh_mirrors/ba/baidu-wangpan-parse 还在为百度网盘的限速而烦恼吗?今天我要向你介绍一款强…...

AI-Shoujo HF Patch:如何让一款日系3D游戏变身专业创作平台?

AI-Shoujo HF Patch:如何让一款日系3D游戏变身专业创作平台? 【免费下载链接】AI-HF_Patch Automatically translate, uncensor and update AI-Shoujo! 项目地址: https://gitcode.com/gh_mirrors/ai/AI-HF_Patch 想象一下,你刚刚下载…...

猫抓浏览器扩展实战:3步掌握网页视频音频资源高效下载

猫抓浏览器扩展实战:3步掌握网页视频音频资源高效下载 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 你是否经常遇到这样的情况&#…...

AI代码质量门禁:基于LLM的智能代码审查实践

1. 项目概述:AI驱动的代码质量守护者最近在开源社区里,我注意到一个挺有意思的项目,叫mustafacagri/ai-quality-gate。光看名字,你大概能猜到它和代码质量、AI有关。简单来说,这是一个利用人工智能技术,在代…...

低资源语言机器翻译:合成数据生成与优化策略

1. 低资源语言机器翻译的挑战与机遇在全球化交流日益频繁的今天,机器翻译技术已经成为打破语言壁垒的重要工具。然而,当我们把目光投向那些使用人数较少、数字资源匮乏的语言时,会发现主流机器翻译系统往往表现欠佳。以非洲的斯瓦希里语、东南…...

零成本调用GPT-4o-mini等大模型:Keyless GPT Wrapper API部署与实战

1. 项目概述与核心价值最近在折腾AI应用开发,尤其是想把手头的一些小工具和开源项目接入大语言模型时,总绕不开一个现实问题:API调用成本。无论是OpenAI的GPT-4o-mini,还是Anthropic的Claude 3 Haiku,按token计费的模式…...

多分辨率融合(MuRF)在计算机视觉中的应用与优化

1. 项目背景与核心价值 视觉基础模型(Visual Foundation Models)正在重塑计算机视觉领域的研发范式。这类模型通过海量数据预训练获得通用视觉表征能力,可迁移到各类下游任务中。但在实际应用中,我们发现单一分辨率的输入往往难以…...

Go语言轻量级Web框架Plain:极简设计、高性能与完全可控的API开发实践

1. 项目概述:一个极简主义的现代Web框架最近在和朋友讨论后端技术选型时,我们聊到了一个老生常谈的话题:面对琳琅满目的现代Web框架,从功能齐全的“巨无霸”到追求极致的“微内核”,开发者究竟该如何选择?这…...

如何高效采集小红书内容?XHS-Downloader的3个核心技巧

如何高效采集小红书内容?XHS-Downloader的3个核心技巧 【免费下载链接】XHS-Downloader 小红书(XiaoHongShu、RedNote)链接提取/作品采集工具:提取账号发布、收藏、点赞、专辑作品链接;提取搜索结果作品、用户链接&…...

快速掌握RePKG:Wallpaper Engine资源提取终极指南

快速掌握RePKG:Wallpaper Engine资源提取终极指南 【免费下载链接】repkg Wallpaper engine PKG extractor/TEX to image converter 项目地址: https://gitcode.com/gh_mirrors/re/repkg 你是否曾经想要提取Wallpaper Engine中的精美壁纸资源,却苦…...

Bili2text终极指南:3步免费将B站视频转文字稿,学习效率提升10倍

Bili2text终极指南:3步免费将B站视频转文字稿,学习效率提升10倍 【免费下载链接】bili2text Bilibili视频转文字,一步到位,输入链接即可使用 项目地址: https://gitcode.com/gh_mirrors/bi/bili2text 还在为整理B站视频内容…...

3个关键步骤解决Zotero SciPDF插件在Zotero 7中的兼容性问题

3个关键步骤解决Zotero SciPDF插件在Zotero 7中的兼容性问题 【免费下载链接】zotero-scipdf Download PDF from Sci-Hub automatically For Zotero7 项目地址: https://gitcode.com/gh_mirrors/zo/zotero-scipdf Zotero SciPDF插件是一个为Zotero文献管理软件设计的强大…...

Zotero GPT完整指南:3步快速上手AI文献分析神器 [特殊字符]

Zotero GPT完整指南:3步快速上手AI文献分析神器 🚀 【免费下载链接】zotero-gpt GPT Meet Zotero. 项目地址: https://gitcode.com/gh_mirrors/zo/zotero-gpt 还在为海量文献阅读发愁吗?Zotero GPT将彻底改变你的学术研究方式&#xf…...

AI技能库:模块化封装大模型能力,提升应用开发效率

1. 项目概述:一个面向AI时代的技能库最近在GitHub上看到一个挺有意思的项目,叫“ai-skills-library”。光看名字,你可能觉得这又是一个收集AI工具列表的仓库,但点进去仔细研究后,我发现它的定位和设计思路,…...

Unity游戏自动翻译终极指南:XUnity.AutoTranslator完全解析

Unity游戏自动翻译终极指南:XUnity.AutoTranslator完全解析 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator 你是否曾经因为语言障碍而无法享受精彩的Unity游戏?是否厌倦了等待官方…...