雷达智富

首页 > 内容 > 程序笔记 > 正文

程序笔记

C++跨平台的Ini文件解析开源代码Leksys' INI Parser

2024-07-15 59

前言

Ini文件在Windows上可以使用GetPrivateProfileString系列函数,在Linux中也有多种可以选择的ini文件解析,比如iniparser,libconfini等,但这些库都需要链接一个动态库或静态库,在项目管理中有点不方便,Leksys’ INI Parser是一个跨平台的ini解析C++源码开源项目,只有一个.hpp文件,在项目中加入这个文件就行,而不需要再链接动态库或静态库。

Leksys’ INI Parser的优点

  • 只有在项目中需要引用单个文件iniparser.hpp中
  • 跨平台(Windows和POSIX)
  • 好用的C++接口
  • 扩展标准INI接口:
    数组(逗号分隔的值,即:“val1,val2,val3”)
    映射(逗号分隔的对,即:“key1:value,key2:value”)
    嵌套节(即:“[父项.子项]”)
    嵌套数组和映射(即:“val1,{val2.1,val2.2},{k31:v31,k32:v32}”)
    文件包含(;#include<File_path>)
  • 可以用于保存和加载任何用户定义的类,只要提供了流运算符
  • 支持跨行
  • 可以加载和保存注释

使用方法

项目地址:https://github.com/Lek-sys/LeksysINI
添加提供的iniparser.hpp到您的C++项目,仅此而已。在代码中,可以使用不同的方法设置和获取值,如下所示:

#include iostream
#include iniparser.hpp

int main(int argc, char** argv)
{
	int ival;
	double dval;
	// Creating ini file object
	INI::File ft;
	// Loading from file
	if (!ft.Load(settings.ini))
	{
		// Loading from stream
		std::ifstream op(opts.ini,std::ios::in);
		if (op.is_open())
			op  ft;
	}
	// Set value1 in section Main to 20
	ft.GetSection(Main)-SetValue(value1,20);
	// get value1 from section Main. If there is no such entry return default value 1
	ival = ft.GetSection(Main)-GetValue(value1,1).AsInt();
	// get value2 from section Main, defaulting to 2
	ival = ft.GetValue(Main:value2,2).AsInt();
	// set value1 in subsection subsect of section Main
	ft.SetValue(Main.subsect:value1,345.5);
	// get value1 from subsection subsect of section Main
	dval = ft.GetSection(Main)-GetSubSection(subsect)-GetValue(value1).AsDouble();
	// set 4th element of array array in section Main to 32.1
	ft.GetSection(Main)-SetArrayValue(array,4,32.1);
	// get 4th element of array array in section Main
	dval = ft.GetSection(Main)-GetValue(array).AsArray()[4].AsDouble();
	// iterate over all sections in file
	for (INI::File::sections_iter it = ft.SectionsBegin(); it != ft.SectionsEnd(); ++it)
	{
		std::cout  Section name:   it-first  std::endl;
		INI::Section* sect = it-second;
		// iterate over all entries in specific section
		for (INI::Section::values_iter it2 = sect-ValuesBegin(); it2 != sect-ValuesEnd(); ++it2)
			std::cout  Entry name:   it2-first  , Entry value:  
					   it2-second.AsString()  std::endl;
	}
	// output to INI file
	ft.Save(settings.ini);
	// output to stream
	std::cout  ft;
}

查看提供的test_app.cpp了解更多使用Leksys IniParser的示例,例如如何获取和设置注释、如何使用映射以及如何保存和加载类。

Ini语法支持

支持带有注释、多行、数组、映射、子部分和包含的扩展ini文件语法。格式如下:

; Comment line
; File inclusion. Absolute or relative path can be used
;#include settings2.ini
; simple line
global_int = 1
; multiline
global_str = Hello! This is just a sample string \
             That is multiline \
             Simple as that

; Section
[Main]
int      = 1                                 ; Integer value
double   = 2.303                             ; Double value
str      = Hello! This is string!            ; String
bool     = true                              ; Boolean value
array    = 1, 202.56, String with space, 5   ; Array
cmp_arr  = {12,3}, {13,5}, {18,9}            ; Array of arrays
cmp_arr2 = a, b, {, String with ,}           ; Array with string, cont. separator
cmp_arr3 = a, b, /, String with /,           ; Same as array cmp_arr2
cmp_arr3 = a, b, String with /{ and /}       ; Array with string, cont. braces
map      = 1:5, 1:3, 2:9, 3:10               ; Map
cmp_map  = a:{1,5,7}, b: {str1, {2,3}}       ; Complex map with arrays as values
cmp_map2 = a:{String with ,,}, b: String     ; Map with string, cont. separator
cmp_map3 = a:String with /,/,, b: String     ; Same as cmp_map2
cmp_map3 = a:String with /{ and /}, b: Str   ; Map with string, cont. braces

; Subsection (Sub1 is considered subsection of section Main)
[Main.Sub1]
ret      = String
ret2     = 201

[Main.Sub2]
; File contents of included file will be placed here
;#include settings/sub2.ini

运行测试ini读写

Leksys’ INI Parser项目提供了测试程序,编译使用cmake,所以编译前需要在环境中安装cmake,参照:http://www.cmake.org/cmake/resources/software.html 进行安装。

Linux中编译和运行

在Linux中,克隆代码到本地,并执行编译:

$ git clone https://github.com/Lek-sys/LeksysINI.git
$ cd LeksysINI
$ mkdir build
$ cd build
$ cmake ../
$ make

执行编译之后,就正常生成了可执行文件test_ini_app,执行即可完成ini文件读写的测试,运行如下:

$ ./test_ini_app -o test.ini

运行结果:

Leksys INIParser test program
Usage: test_app [-i input_file] [-o output_file]
Pass [input_file] for optional loading file test (TEST11)
Pass [output_file] for optional saving file test (TEST12)
---------------------------------------------------------
[TEST1] passed
[TEST2] passed
[TEST3] passed
[TEST4] passed
[TEST5] passed
[TEST6] passed
[TEST7] passed
[TEST8] passed
[TEST9] passed
[TEST10] passed
[TEST11] passed
[TEST12] passed
Optional [TEST13] (file loading) SKIPPED
[TEST14] passed! (Look in test.ini for your file)!
!!! [SUCCESS] !!!

输出到test.ini文件中的内容如下:

[MainProg]
value1 = 456
value2_0 = false
value2_1 = true
value2_2 = 0
value2_3 = 1
value2_4 = FALSE
value2_5 = TRUE
value2_6 = false
value2_7 = true
value3 = true,105,200.55000000000001,String,,,700.66999999999996 ;Test array
value_test = 1 ;Testing value

[MainProg2]
cmp_array1 = {12,3}, {13,5}, {18,9}
cmp_array2 = Str1, Str2, {{Str3,,3}}, Str4\,\,\{\,\,\}, {Str5\,,\{\{}
map1 = 1:5, 1:3, 2:9, 3:10
map2 = Str1:5, Str2:3, Str3:{:,,:}
map3 = Str1:{Sub1,{\,,\\{\\{Sub2,},{,:Sub3}}, Str2:1
value1 = 1 ;Comment 2
value_test = 1 ;Testing value

[MainProg2.Sub1]
test_val = {1,120.55500000000001,3} ;User-defined class

[MainProg2.Sub1.SubSub1]
value1 = 120

Windows中编译和运行

Windows中可以用cmake的gui进行编译,也可以输入一下命令:

$ mkdir build; cd build
$ cmake this_file_dir
$ %VS140COMNTOOLS%\vsvars32.bat
$ nmake
更新于:3个月前
赞一波!

文章评论

评论问答