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

news2024/9/21 4:26:06

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                         = 100
        host                           = 192.168.1.2
        port                           = 8087
        rate                           = 9.98
        
        
        [body]
        accept                         = XML
        data                           = json
        length                         = 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                         = 100
        host                           = 192.168.1.2
        port                           = 8087
        rate                           = 9.98
        
        [body]
        accept                         = XML
        data                           = json
        length                         = 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                         = 100
        host                           = 192.168.1.2
        port                           = 8087
        rate                           = 9.98
        
        
        [body]
        accept                         = XML
        data                           = iniparser
        length                         = 200
        msg                            = success
      

4.3 遍历section和键值

  • ini文件内容
    •   [head]
        accecpt                        = */*
        length                         = 100
        host                           = 192.168.1.2
        port                           = 8087
        rate                           = 9.98
        
        
        [body]
        accept                         = XML
        data                           = iniparser
        length                         = 200
        msg                            = success
      
  • 测试代码
    •   #include <stdio.h>
        #include <iniparser.h>
        
        int main(){
        
        	// 加载配置
        	dictionary* ini = iniparser_load("config.ini");
        	if(ini == NULL){
        		return -1;
        	}
        	
        
        	// 遍历section
        	int 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下的key
        	int 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.coloradmin.cn/o/1611943.html

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

相关文章

数据结构10:堆和堆排序

文章目录 树的概念及结构树的概念树的相关概念树的表示树在实际中的应用表示文件系统的目录树结构 二叉树概念及结构概念特殊的二叉树二叉树的性质二叉树的存储结构顺序存储链式存储 二叉树的顺序结构及实现二叉树的顺序结构堆的概念及结构 堆的实现堆的插入堆的删除堆的创建向…

【大数据】TiDB: A Raft-based HTAP Database

文章目录 数据库知识介绍数据库系统的ACID特性分布式系统和CAP理论关系型数据库与非关系型数据库关系型数据库非关系型数据库 OldSQL、NoSQL、NewSQLOldSQLNoSQLNewSQL OLTP、OLAP、HTAP 前言&#xff1a;为什么选择TiDB学习&#xff1f;pingCAP介绍TiDB介绍TiDB的影响力TiDB概…

Wireshark TS | 再谈应用传输缓慢问题

问题背景 来自于朋友分享的一个案例&#xff0c;某某客户反馈电脑应用软件使用时打开很慢&#xff0c;并提供了一个慢时所捕获的数据包文件以及服务端 IP。以前也说过&#xff0c;所谓的慢有很多种现象&#xff0c;也会有很多原因引起&#xff0c;在没有更多输入条件的情况下&…

Redis集合[持续更新]

Redis&#xff08;全称&#xff1a;Remote Dictionary Server 远程字典服务&#xff09;是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库&#xff0c;并提供多种语言的 API。 数据结构 1. string 字符串 字符串类型是 Redis 最…

云知识库怎么搭建才适合中小企业?用这几个工具很轻松

当我们想到知识库时&#xff0c;可能会联想到庞大的公司和复杂的系统&#xff0c;但实际上&#xff0c;随着技术的发展&#xff0c;中小企业也可以利用各种工具来建立自己的云知识库。这样不仅能够提升企业的知识管理效率&#xff0c;还能优化客户服务流程。这篇文章会介绍三款…

【QT+QGIS跨平台编译】182:【QGIS+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、qgis模块介绍二、QGIS下载三、文件分析四、pro文件五、编译实践一、qgis模块介绍 qgis模块作为QGIS启动模块,集成底层所有的模块。 二、QGIS下载 QGIS网址: QGIS Source Download 获取qgis.tar.bz2文件。 三、文件分析 解压缩qgis.tar.bz2文件,进入到qgis\…

编写Spark独立应用程序

执行本文之前&#xff0c;先搭建好spark的开发环境&#xff0c;我目前只搭建了standalone模式&#xff0c;参考链接 &#xff1a; Spark Standalone模式部署-CSDN博客 1. 安装sbt 1&#xff09;下载sbt 网址&#xff1a;https://www.scala-sbt.org/download.html &#xff0c…

# Win10 打不开【本地组策略编辑器】解决方案

Win10 打不开【本地组策略编辑器】解决方案 段子手168 问题描述&#xff1a; 当在 WIN R 打开【运行】输入&#xff1a;gpedit.msc 打开【本地组策略编辑器】时&#xff0c;出现错误时&#xff0c; 或者在【计算机管理】中 没有【本地用户和组】这一项。 可以试一下以下方…

8.MMD ray渲染主流常用插件介绍

导入一个场景&#xff0c;做好基础操作 导入控制器、天空盒、材质 1. AutoLuminous4 自发光的插件 ![[Pasted image 20240421103420.png]] 拖进去以后可以让场景中的自发光材质发光 也可以让不发光的材质强行发光 打开MME&#xff0c;找到AL_EmitterRT 展开场景&#x…

解线性方程组——直接解法:LU分解、PLU分解(类似列主元消去法) | 北太天元

L: lower triangular 下三角 U: upper triangular 上三角 LU 分解&#xff0c;顾名思义&#xff0c;为 把一个 矩阵 分成 一个下三角矩阵 乘上一个上三角矩阵的形式。 Example 为什么可以这样 几个基本的初等行变换&#xff0c;可以自己验算一下&#xff0c;等式的左边与右边…

spring高级篇(二)

1、Aware和InitializingBean Aware和InitializingBean都与Bean的生命周期管理相关。 Aware接口: 概念: Aware接口是Spring框架中的一个标记接口&#xff0c;它表示一个类能够感知到&#xff08;aware of&#xff09;Spring容器的存在及其特定的环境。Spring框架提供了多个Awar…

一周学会Django5 Python Web开发-Django5模型数据修改

锋哥原创的Python Web开发 Django5视频教程&#xff1a; 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计47条视频&#xff0c;包括&#xff1a;2024版 Django5 Python we…

小图标还不会设计!

ICON图标设计 hello&#xff0c;我是小索奇 image-20230805225451447 你有好奇过这样的图标如何设计的吗&#xff1f; 其实非常简单&#xff0c;仅需要一行代码即可完成&#xff0c;本篇文章就带伙伴们使用&#xff0c;每天看一篇&#xff0c;简单易懂&#xff0c;日久技长~…

5 款免费数据恢复工具,用于恢复误删数据

数据恢复工具是通过组装幸存的片段、从剩余的片段重建或使用备份来重新获得对因存储损坏、人为错误或意外中断而丢失的文件的访问权限的行为。它是将丢失、损坏、意外擦除或以其他方式无法访问的数据恢复到服务器、计算机、手机或存储设备的过程。 在大多数情况下&#xff0c;数…

kaggle 泰坦尼克使用xgboost 得分0.73684

流程 导入所要使用的包引入kaggle的数据集csv文件查看数据集有无空值填充这些空值提取特征分离训练集和测试集调用模型 导入需要的包 import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns import warnings warnings.filterwarni…

人人都能玩赚数字人操作员 数字人直播搭建/多路开播/选品技巧/0-1开播流程

课程目录 01 数字人工业化直播车间打造 02 数字人直播规则及防封技巧 03 数字人直播间搭建步骤流程 04 数字人直播行业应用盘点 05 数字人直播多平台多路开播 06 数字人高成交循环话术运营 07 数字人直播选品及组品技I5 08 数字人直播0-1流程 09 工业化直播0-1流程 网…

Axure中的样式

样式 首先说一下Axure里面的原点位置 如下图&#xff1a; 还有一个办法是我们选中我们的按钮&#xff0c;如上图&#xff0c;然后打开右边的样式&#xff0c;可以看按钮的x&#xff0c;y属性&#xff0c;类似于游戏中unity软件的x&#xff0c;y属性&#xff0c;类似于html中…

【JVM系列】关于静态块、静态属性、构造块、构造方法的执行顺序

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

数字时代的智慧演奏

数字化时代&#xff0c;工业不再是孤独的机器运转&#xff0c;而是演绎着一场智能与数据的华丽交响。无数智能节点的联动&#xff0c;数据的涌动&#xff0c;成为工业的新活力&#xff0c;同时也是创新的源泉。 工业互联网将每个机器、设备连接在一起&#xff0c;打破了原本独立…

【数据结构练习题】堆——top-k问题

♥♥♥♥♥个人主页♥♥♥♥♥ ♥♥♥♥♥数据结构练习题总结专栏♥♥♥♥♥ ♥♥♥♥♥上一章&#xff1a;【数据结构练习题】二叉树(1)——1.相同的树2.另一颗树的子树3.翻转二叉树4.平衡二叉树5.对称二叉树♥♥♥♥♥ 文章目录 1.top-k问题1.1问题描述1.2思路分析1.3绘图分析…