C语言开源库iniparser解析ini文件

1 ini文件介绍

  • INI(Initialization File)文件是一种简单直观的数据存储格式,常用于配置应用程序的初始化设置。这种文件通常包含若干个节(section)和键值对(key-value pairs)。INI文件的每一部分都是自描述性的,易于阅读和编辑,使得非程序员也能轻易理解并修改配置参数。
  • INI文件因其简单易用性而在许多编程语言中广泛应用,尤其是在Windows操作系统中,很多应用程序都采用INI文件作为配置文件。当然,随着XML、JSON等更丰富、更结构化的数据交换格式的普及,INI文件在现代应用程序中的使用相对减少,但在一些轻量级应用或对启动速度有较高要求的情况下,仍然是一种常见且实用的配置文件格式。

2 ini文件结构

  • 节(Section):INI文件中的各个部分通过方括号 [] 包裹的名称来定义,例如 [Section1]。每个节可以包含多个键值对。
  • 键值对(Key-Value Pairs):键和值之间用等号 = 分隔,如 key1=value1。键通常是描述性质的字符串,而值则可以是字符串、数字或其他类型的数据。
  • 注释:注释行以分号 ; 开始,直到行尾都被视为注释内容,不会被程序解析。
  • 多行值:某些INI解析器允许值跨越多行,通常通过在行尾添加反斜杠 \ 来延续到下一行

iniparser

  • iniparser 是一个开源的 C 语言库,用于解析和操作 INI 格式的配置文件
  • 使用 iniparser 库的应用程序可以很方便地读取和解析INI文件中的配置信息,大大简化了对配置文件的处理工作,降低了程序的开发复杂度。由于其开源属性,开发者可以根据自己的需求自由使用、研究和改进该库。

3 相关API

3.1 加载ini文件

  •   /**  @brief  从ini格式的配置文件中加载数据*  @param  [IN]  ininame  要打开的ini格式文件            *  @return != NULL 返回一个指向dictionary结构的指针*          == NULL 加载ini文件失败*/dictionary * iniparser_load(const char *ininame);
    

3.2 获取键值

  •   /**  @brief  获取指定键(key)对应的字符串类型的值*  @param  [IN]  d  dictionary结构的指针   *  @param  [IN]  key  要查找的键,通常格式为 "section:key",表示要获取哪个节(section)下的哪一项(key)的值。*  @param  [IN]  def  当键不存在或者其值不是字符串时的默认返回值。如果没有找到对应键,函数将返回此默认值。    *  @return 如果找到了相应的键,返回键值对应字符串* 			如果没有找到匹配的键,返回def指定的字符串值*/const char * iniparser_getstring(const dictionary *d, const char *key, const char *def);/**  @brief  获取指定键(key)对应的整数值*  @param  [IN]  d  dictionary结构的指针   *  @param  [IN]  key  要查找的键,通常格式为 "section:key",表示要获取哪个节(section)下的哪一项(key)的值。*  @param  [IN]  notfound  当键不存在或者其值不能被转换为整数时,函数将返回这个默认值。   *  @return 如果找到了相应的键,并且其值可以被成功转换为整数,则返回该整数值。*		   如果没有找到匹配的键,或者该键对应的值无法转换为整数,则返回 notfound 参数提供的默认值。*/int iniparser_getint(const dictionary * d, const char * key, int notfound);/**  @brief  获取指定键(key)对应的浮点型值*  @param  [IN]  d  dictionary结构的指针   *  @param  [IN]  key  要查找的键,通常格式为 "section:key",表示要获取哪个节(section)下的哪一项(key)的值。*  @param  [IN]  notfound  当键不存在或者其值无法转换为双精度浮点数时,函数返回的默认值。*  @return 如果找到了相应的键,并且其值能成功转换为一个双精度浮点数,则返回该浮点数。*		   如果没有找到匹配的键,或者键的值不能被解释为一个有效的双精度浮点数,则返回 notfound 参数所提供的默认值。*/double iniparser_getdouble(const dictionary *d, const char *key, double notfound);
    

3.3 设置键值

  •   /**  @brief  设置或修改 ini  配置文件中某个键值对*  @param  [IN]  d  dictionary结构的指针   *  @param  [IN]  entry  字符串形式的键值对标识符,格式通常是 "section:key",表明您要在哪个节(section)下的哪个键(key)上设置或修改值(val)。*						key值存在则修改对应val,key值不存在则会新增*  @param  [IN]  val: 要设置的新值,作为字符串传递。*  @return 返回0表示设置成功*/int iniparser_set(dictionary *ini, const char *entry, const char *val);
    

3.4 移除键值

  •   /**  @brief  移除 ini 配置文件中某个键值对*  @param  [IN]  d  dictionary结构的指针   *  @param  [IN]  entry  字符串形式的键名,包括可选的部分名称(section)和键(key)*					     如果不指定key,则会移除整个section*/void iniparser_unset(ini, const char *entry);
    

3.5 判断键是否存在

  •   /**  @brief  判断 ini 配置文件是否存在某个键值*  @param  [IN]  d  dictionary结构的指针   *  @param  [IN]  entry  字符串形式的键值对标识符,格式通常是 "section:key"*  @return 返回1表示存在,返回0表示不存在*/int iniparser_find_entry(const dictionary *ini, const char *entry);
    

3.6 获取section个数

  •   /**  @brief  获取ini配置文件中section的数量*  @param  [IN]  d  dictionary结构的指针             *  @return 成功返回section个数,失败返回 -1*/int iniparser_getnsec(const dictionary * d);/**  @brief  获取某个section值*  @param  [IN]  d  dictionary结构的指针*  @param  [IN]  n  指定获取第几个section值                  *  @return 成功返回获取到的section值,失败返回NULL*/const char *iniparser_getsecname(const dictionary * d, int n);
    

3.7 获取section下key个数

  •   /**  @brief  获取ini配置文件中某个section的key个数*  @param  [IN]  d  dictionary结构的指针 *  @param  [IN]  s  section          *  @return 返回指定section下的key个数*/int iniparser_getsecnkeys(dictionary * d, char * s); /**  @brief  获取ini配置文件中某个section的所有key*  @param  [IN]  d  dictionary结构的指针 *  @param  [IN]  s  section      *  @param  [OUT]  keys  通过这个参数输出key,也可以通过返回值获取     *  @return  成功返回指定section下的key,失败返回NULL*/const char **iniparser_getseckeys(const dictionary *d, const char *s, const char **keys)
    

3.8 保存dictionary对象到文件中

  •   /**  @brief  保存dictionary对象到文件中*  @param  [IN]  d  dictionary结构的指针   *  @param  [IN]  f  已打开的文件描述符*/void iniparser_dump_ini(const dictionary *d, FILE *f);
    

3.9 释放dictionary对象

  •   /**  @brief  释放dictionary对象*  @param  [IN]  d  dictionary结构的指针   */void iniparser_freedict(dictionary * d);
    

4 演示

4.1 获取键值

  • ini文件内容
    •   [head]accecpt                        = */*length                         = 100host                           = 192.168.1.2port                           = 8087rate                           = 9.98[body]accept                         = XMLdata                           = jsonlength                         = 200
      
  • 测试代码
    •   #include <stdio.h>#include <iniparser.h>int main(){// 加载配置dictionary* ini = iniparser_load("config.ini");if(ini == NULL){return -1;}// 获取键值const char* cHeadHost = iniparser_getstring(ini, "head:host", "127.0.0.1");printf("cHeadHost %s\n", cHeadHost);const char* cBodyData = iniparser_getstring(ini, "body:data", "welcome");printf("cBodyData %s\n", cBodyData);int iHeadPort = iniparser_getint(ini, "head:port", 80);printf("iHeadPort %d\n", iHeadPort);double iHeadReate = iniparser_getdouble(ini, "head:rate", 9.99);printf("iHeadReate %.2lf\n", iHeadReate);// 释放dictionary对象iniparser_freedict(ini);return 0;}
      
  • 打印结果
    • 在这里插入图片描述

4.2 设置键值

  • ini文件内容
    •   [head]accecpt                        = */*length                         = 100host                           = 192.168.1.2port                           = 8087rate                           = 9.98[body]accept                         = XMLdata                           = jsonlength                         = 200
      
  • 测试代码
    •   #include <stdio.h>#include <iniparser.h>int main(){// 加载配置dictionary* ini = iniparser_load("config.ini");if(ini == NULL){return -1;}// 有对应键值则修改int ret = iniparser_set(ini, "body:data", "iniparser");if (ret != 0){printf("iniparser_set body:data failed.\n");}// 没有对应键值则添加ret = iniparser_set(ini, "body:msg", "success");if (ret != 0){printf("iniparser_set body:data failed.\n");}// 设置值成功后要进行保存FILE* fp = fopen("config.ini", "w");if( fp == NULL ) {printf("open ini file failed.\n");return -1;}// 保存dictionary对象到file iniparser_dump_ini(ini, fp);fclose(fp);// 释放dictionary对象iniparser_freedict(ini);return 0;}
      
  • 设置后新的ini文件内容
    •   [head]accecpt                        = */*length                         = 100host                           = 192.168.1.2port                           = 8087rate                           = 9.98[body]accept                         = XMLdata                           = iniparserlength                         = 200msg                            = success
      

4.3 遍历section和键值

  • ini文件内容
    •   [head]accecpt                        = */*length                         = 100host                           = 192.168.1.2port                           = 8087rate                           = 9.98[body]accept                         = XMLdata                           = iniparserlength                         = 200msg                            = success
      
  • 测试代码
    •   #include <stdio.h>#include <iniparser.h>int main(){// 加载配置dictionary* ini = iniparser_load("config.ini");if(ini == NULL){return -1;}// 遍历sectionint sectionNum = iniparser_getnsec(ini);if(sectionNum != -1){for(int i = 0; i < sectionNum; i++){const char* cSection = iniparser_getsecname(ini, i);	if(cSection != 0){printf("cSection : %s\n", cSection);}}}// 遍历某个section下的keyint keyNum = iniparser_getsecnkeys(ini, "body");//获取dictionary对象某个section下所有的key char keys[10][1024] = { 0 };const char **p = (const char **)keys;const char **retKeys = iniparser_getseckeys(ini, "body", p); for (int i = 0; i < keyNum; i++){printf("%s ", p[i]);}printf("\n");// 释放dictionary对象iniparser_freedict(ini);return 0;}
      
  • 打印结果
    • 在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring AOP(面向切面编程)

1.Spring AOP 简介 1.1 AOP概述 AOP 为 Aspect Oriented Programming 的缩写&#xff0c;意思为面向切面编程, 是通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP 是 OOP 的延续&#xff0c;是Spring框架中的一个重要内容&#xff0c;是函数式编程的一…

FPGA Quartus IP核 打开使用

两种Quartus版本下的IP核&#xff0c;从使用者的角度来看仅仅是配置界面不同&#xff0c;在参数设置和使用方法上基本一致。本文以“MegaWizard Plug-In Manager”中的FIR Compiler IP核使用为例。 Quartus的FIR IP核属于收费IP&#xff0c;如果是个人学习使用需要对IP核单独破…

C++ 深入理解 继承

本篇文章将谈谈一下几个问题&#xff1a; 1.基类和派生类对象赋值转换 2.继承中的作用域 3.派生类的默认成员函数 4.复杂的菱形继承及菱形虚拟继承 5.其他 1.基类和派生类对象赋值转换 1.派生类对象 可以赋值给 基类的对象 / 基类的指针 / 基类的引用。这里有个形象的说法叫切…

【电控笔记2.5】位置闭环回路设计

总结 List item 位置控制器 加入前馈 总结

SpringBoot基于JavaWeb的菜鸟驿站快递管理系统ssm

前端&#xff1a;vue.jsElementUI 编程语言: java 框架&#xff1a; ssm/springboot 详细技术&#xff1a;springboot springbootvueMYSQLMAVEN 数据库: mysql5.7 数据库工具&#xff1a;Navicat/SQLyog都可以 ide工具&#xff1a;IDEA 或者eclipse 对菜鸟驿站快递管理系统设计…

会议文字记录工具【钉钉闪记】

当开会时&#xff0c;需要文字记录会议内容&#xff0c;但是打字又慢&#xff0c;可以使用钉钉闪记。 钉钉工作台直接搜索-钉钉闪记

ADSP-21479的开发详解九(CCES开发详解)

硬件准备 ADSP-21479EVB开发板&#xff1a; 产品链接&#xff1a;https://item.taobao.com/item.htm?id555500952801&spma1z10.5-c.w4002-5192690539.11.151441a3Z16RLU AD-HP530ICE仿真器&#xff1a; 产品链接&#xff1a;https://item.taobao.com/item.htm?id38007…

【PythonCode】力扣Leetcode16~20题Python版

【PythonCode】力扣Leetcode16~20题Python版 前言 力扣Leetcode是一个集学习、刷题、竞赛等功能于一体的编程学习平台&#xff0c;很多计算机相关专业的学生、编程自学者、IT从业者在上面学习和刷题。 在Leetcode上刷题&#xff0c;可以选择各种主流的编程语言&#xff0c;如C…

React【Day4下+5】

环境搭建 使用CRA创建项目&#xff0c;并安装必要依赖&#xff0c;包括下列基础包 Redux状态管理 - reduxjs/toolkit 、 react-redux路由 - react-router-dom时间处理 - dayjsclass类名处理 - classnames移动端组件库 - antd-mobile请求插件 - axios 配置别名路径 1. 背景知识…

【Linux 进程间通信】管道

文章目录 1.System V 标准介绍2.进程间通信的方式&#xff1f;3.管道&#xff08;匿名管道&#xff09; 1.System V 标准介绍 ①&#x1f34e; System V 实际上就是一个标准&#xff08;“ 行业领头羊制定出来的专利 " &#xff09; 2.进程间通信的方式&#xff1f; …

linux下摄像头设置固定的设备名

目录 2.热插拔udev机制 3.设置udev的规则 1.查看usb ID 2. 查看usb设备的信息 3.编译规则 4.拓展 1.问题的出现 通过我之前的文章配置完摄像头的开机自启动之后我们会发现有的时候会出现启动不了的情况&#xff0c;通过实验我发现是摄像头的设备名发生了改变&#xff0c;…

ADSP-21479的开发详解五(AD1939 C Block-Based Talkthru 48 or 96 kHz)音频直通

硬件准备 ADSP-21479EVB开发板&#xff1a; 产品链接&#xff1a;https://item.taobao.com/item.htm?id555500952801&spma1z10.5-c.w4002-5192690539.11.151441a3Z16RLU AD-HP530ICE仿真器&#xff1a; 产品链接&#xff1a;https://item.taobao.com/item.htm?id38007…

开源数据集分享——猫脸码客

开源数据集分享&#xff0c;让数据更自由流通——猫脸码客带你走进数据的新世界 在数字化时代的浪潮中&#xff0c;数据已经成为推动社会进步的重要力量。然而&#xff0c;数据的获取与利用往往受到种种限制&#xff0c;使得许多有价值的信息难以被充分挖掘。幸运的是&#xf…

适配器模式【结构型模式C++】

1.概述 适配器模式是一种结构型设计模式&#xff0c; 又称为变压器模式、包装模式&#xff08;Wrapper&#xff09; 将一个类的接口变换成客户端所期待的另一种接口&#xff0c;从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。 2.结构 Target&#xff1a;适配…

Leetcode算法训练日记 | day31

专题九 贪心算法 一、分发饼干 1.题目 Leetcode&#xff1a;第 455 题 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#xff0c;都有一个胃口值 g[i]&#xff0c;这是能让孩子们满足胃口的…

【算法一则】矩阵置零 【矩阵】【空间复用】

题目 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0,1],[0,0,0],[1,0,1]]示例 2&#xff1a; …

冰达ROS机器人快速使用指南

欢迎来到《冰达ROS机器人极简使用指南》 Q&#xff1a;这份教程适合谁&#xff1f; A&#xff1a;适合完全0基础新手&#xff0c;需要快速跑起来机器人的基本功能。也适合技术大佬需要快速的了解冰达ROS机器人的使用方法。 Q&#xff1a;这份教程内容很少&#xff0c;是不是…

机器学习基本流程

Jupyter Notebook 代码连接&#xff1a; machine_learning_demo machine_learning_ensembles Step 1: Imports and Configuration import pandas as pd import numpy as np import copy import json import pickle import joblib import lightgbm as lgb import optuna impor…

国产数据库实践:亚信安慧AntDB在DTC 2024展示创新实力

4月12至13日&#xff0c;我国数据库行业最具影响力的活动之一——第十三届『数据技术嘉年华』(DTC 2024) 在京成功举办&#xff0c;业内众多专家学者、技术领袖、各行业客户和实力厂商均到场参会。亚信安慧AntDB数据库总架构师洪建辉受邀参与“数据库一体化”专题论坛&#xff…

Stylus精讲:网页设计新境界【写作AI一键生成】

首先&#xff0c;这篇文章是基于笔尖AI写作进行文章创作的&#xff0c;喜欢的宝子&#xff0c;也可以去体验下&#xff0c;解放双手&#xff0c;上班直接摸鱼~ 按照惯例&#xff0c;先介绍下这款笔尖AI写作&#xff0c;宝子也可以直接下滑跳过看正文~ 笔尖Ai写作&#xff1a;…