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

 更新时间:2024年04月26日 10:49:39   作者:大草原的小灰灰  
INI(Initialization File)文件是一种简单直观的数据存储格式,常用于配置应用程序的初始化设置,使用 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                         = 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;
  }

打印结果

到此这篇关于C语言开源库iniparser解析ini文件的文章就介绍到这了,更多相关C语言iniparser解析ini文件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • QT5编译使用QFtp的方法步骤

    QT5编译使用QFtp的方法步骤

    这篇文章主要介绍了QT5编译使用QFtp的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • C++实现添加图片水印到PDF文档

    C++实现添加图片水印到PDF文档

    水印是显示在文档内容后面的淡色文字或图片,可以用于指示文档的状态(保密、草稿等),本文主要为大家介绍了如何使用 Spire.PDF for C++ 在 PDF 文档中添加图片水印,需要的可以参考下
    2023-11-11
  • 详解DAG上的DP

    详解DAG上的DP

    DAG:有向无环图。DAG是学习动态规划的基础,很多问题都可以直接转化为DAG上的最长路、最短路或路径计数问题。本文将详细介绍DAG上的DP。
    2021-05-05
  • C语言五子棋小游戏实现代码

    C语言五子棋小游戏实现代码

    这篇文章主要为大家详细介绍了C语言五子棋小游戏实现代码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • C语言实现停车场管理系统

    C语言实现停车场管理系统

    这篇文章主要为大家详细介绍了C语言实现停车场管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-11-11
  • vs2022 x64 C/C++和汇编混编(案例代码)

    vs2022 x64 C/C++和汇编混编(案例代码)

    这篇文章主要介绍了vs2022 x64 C/C++和汇编混编,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-02-02
  • 利用C++实现简易的.ini配置文件解析器

    利用C++实现简易的.ini配置文件解析器

    这篇文章主要为大家详细介绍了如何基于C++编写一个简易的.ini配置文件解析器,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以了解一下
    2023-03-03
  • QT实现FTP上传文件

    QT实现FTP上传文件

    这篇文章主要为大家详细介绍了QT实现FTP上传文件,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • C++中的强制类型转换操作详解

    C++中的强制类型转换操作详解

    C++中提供了四种强制类型转换技术:static_cast、dynamic_cast、reinterpret_cast和const_cast。这些技术能够在需要时将一种类型转换为另一种类型,但需要注意它们的适用条件和安全性。程序员需要根据具体情况选择合适的强制类型转换方式,以确保程序的正确性和可靠性
    2023-04-04
  • C语言 深入浅出讲解指针的使用

    C语言 深入浅出讲解指针的使用

    指针是C语言中一个非常重要的概念,也是C语言的特色之一。使用指针可以对复杂数据进行处理,能对计算机的内存分配进行控制,在函数调用中使用指针还可以返回多个值
    2022-03-03

最新评论