基于C/C++的非系统库自定义读写ini配置

news2024/11/28 8:32:06

INI文件由节、键、值组成。

[section]

参数

(键=值)

name=value

这里将常用的操作方式封装成了一个dll供外部使用

// 下列 ifdef 块是创建使从 DLL 导出更简单的
// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 LIBCFG_EXPORTS
// 符号编译的。在使用此 DLL 的
// 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
// LIBCFG_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
// 符号视为是被导出的。
#ifdef LIBCFG_EXPORTS
#define LIBCFG_API __declspec(dllexport)
#else
#define LIBCFG_API __declspec(dllimport)
#endif
LIBCFG_API int cfg_init(const char* cfg_name);
LIBCFG_API void cfg_free();
LIBCFG_API char* cfg_get(const char* section, const char* name);
LIBCFG_API int cfg_set(const char* section, const char* name, const char* value);
LIBCFG_API int cfg_save(const char* cfg_name);
LIBCFG_API void cfg_print();
LIBCFG_API int cfg_log(char* logfile, unsigned char logLevel);
LIBCFG_API int cfg_delete(const char* section, const char* name);

定义相关操作接口的函数指针

typedef  int(*Cfg_init)(const char* cfg_name);
typedef  void(*Cfg_free)();
typedef char*(*Cfg_get)(const char* section, const char* name);
typedef  int(*Cfg_set)(const char* section, const char* name, const char* value);
typedef  int(*Cfg_save)(const char* cfg_name);
typedef  void(*Cfg_print)();
typedef  int(*Cfg_log)(char* logfile, unsigned char logLevel);
typedef  int(*Cfg_delete)(const char* section, const char* name);

定义API函数变量

int cfg_load = UNZ_ERRNO;

HMODULE cfgDll;
static Cfg_init	_cfg_init;
static Cfg_free	_cfg_free;
static Cfg_get	_cfg_get;
static Cfg_set	_cfg_set;
static Cfg_save	_cfg_save;
static Cfg_print _cfg_print;
static Cfg_log	 _cfg_log;
static Cfg_delete _cfg_delete;

接口导出:

int load_cfg() {
	char path[] = "D:\\D-Pro\\Summary\\libcfg\\Release\\libcfg.dll";
	if (cfg_load == UNZ_OK)
		return UNZ_OK;
	cfgDll = LoadLibrary(path);
	if (cfgDll != NULL) {
		_cfg_init = (Cfg_init)GetProcAddress(cfgDll, "cfg_init");
		_cfg_free = (Cfg_free)GetProcAddress(cfgDll, "cfg_free");
		_cfg_get = (Cfg_get)GetProcAddress(cfgDll, "cfg_get");
		_cfg_set = (Cfg_set)GetProcAddress(cfgDll, "cfg_set");
		_cfg_save = (Cfg_save)GetProcAddress(cfgDll, "cfg_save");
		_cfg_print = (Cfg_print)GetProcAddress(cfgDll, "cfg_print");
		_cfg_log = (Cfg_log)GetProcAddress(cfgDll, "cfg_log");
		_cfg_delete = (Cfg_delete)GetProcAddress(cfgDll, "cfg_delete");
		cfg_load = UNZ_OK;
		return UNZ_OK;
	}
	return UNZ_ERRNO;
}

接口调用:

int cfg_init(const char *cfgfile) {
	load_cfg();
	if (cfg_load == UNZ_ERRNO)
		return UNZ_ERRNO;
	_cfg_init(cfgfile);
}

void cfg_free() {
	load_cfg();
	if (cfg_load == UNZ_ERRNO)
		return;
	_cfg_free();
}
char* cfg_get(const char* section, const char* name) {
	load_cfg();
	if (cfg_load == UNZ_ERRNO)
		return NULL;
	return _cfg_get(section,name);
}
int cfg_set(const char* section, const char* name, const char* value) {
	load_cfg();
	if (cfg_load == UNZ_ERRNO)
		return UNZ_ERRNO;
	return _cfg_set(section, name, value);
}
int cfg_delete(const char* section, const char* name) {
	load_cfg();
	if (cfg_load == UNZ_ERRNO)
		return UNZ_ERRNO;
	return _cfg_delete(section, name);
}
int cfg_save(const char* cfg_name) {
	load_cfg();
	if (cfg_load == UNZ_ERRNO)
		return UNZ_ERRNO;
	return _cfg_save(cfg_name);
}
void cfg_print() {
	load_cfg();
	if (cfg_load == UNZ_ERRNO)
		return ;
	_cfg_print();
}
int cfg_log(char* logfile, unsigned char logLevel) {
	load_cfg();
	if (cfg_load == UNZ_ERRNO)
		return UNZ_ERRNO;
	return _cfg_log(logfile, logLevel);
}

应用示例:

创建一个config.ini文件

int main() {
	cfg_set("config","第一个节点","节点1的值");
	cfg_save("config.ini");
	cfg_free();
	return 0;
}

读取config.in文件指定节点值

#include "libcfg.h"
int main() {
	char* value = NULL;
	cfg_init("config.ini");
	value = cfg_get("config","第一个节点");
	printf("\nvalue:%s\n", value);
	cfg_free();
	return 0;
}

修改节点的值并保存

#include "libcfg.h"
int main() {
	char* value = NULL;
	cfg_init("config.ini");
	value = cfg_get("config","第一个节点");
	printf("\nvalue:%s\n", value);
	cfg_set("config", "第一个节点","修改值测试");
	value = cfg_get("config", "第一个节点");
	printf("\nvalue:%s\n", value);
	cfg_save("config.ini");
	cfg_free();
	return 0;
}

 

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

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

相关文章

紫光FPGA DDR3 IP使用和注意事项(axi4协议)

紫光DDR3 IP使用 对于紫光ddr3 IP核的使用需要注意事情。 阅读ddr ip手册: 1、注意:对于写地址通道,axi_awvalid要一直拉高,axi_awready才会拉高。使用的芯片型号时PG2L100H-6FBG676,不同的型号IP核接口和axi的握手协…

wireshark下载安装

下载 Wireshark Download 等待下载完成 安装 双击 下面的一定垚勾选上 下图的也一定要勾选上 修改为不重启,不需要重启也是正常的

嵌入式中的门电路详讲

NOT门电路 NOT(非门)是数字逻辑电路中的一种基本逻辑门,也称为反相器。它执行的是逻辑非操作,即将输入信号取反。NOT门具有一个输入和一个输出。 A输入,B输出,以下是真值表: A B 0 1 1 0 AND门电路 AND(与门)是数字逻辑电路中的一种基本逻辑门,用于执行逻辑与操作。…

从 0 开始实现一个 SpringBoot + Vue 项目

从 0 开始实现一个 SpringBoot Vue 项目 从 0 开始实现一个 SpringBoot Vue 项目软件和工具创建 SpringBoot 后端项目创建 MySQL 数据库配置文件实现增删改查接口Model 层mapper 层service 层controller 层测试 从 0 开始实现一个 SpringBoot Vue 项目 软件和工具 后端开发…

jmeter如何循环运行到csv文件最后一行后停止

1、首先在线程组中设置’循环次数‘–勾选永远 2、csv数据文件设置中设置: 遇到文件结束符再次循环?——改为:False 遇到文件结束符停止线程?——改为:True 3、再次运行就会根据文档的行数运行数据 (如果需要在循环控制器中&…

[python]用python获取EXCEL文件内容并保存到DBC

目录 关键词平台说明背景所需库实现过程方法1.1.安装相关库2.代码实现 关键词 python、excel、DBC、openpyxl 平台说明 项目Valuepython版本3.6 背景 在搭建自动化测试平台的时候经常会提取DBC文件中的信息并保存为excel或者其他文件格式,用于自动化测试。本文…

STL容器之string(上)

目录 什么是STL string类 string类常见接口 string类的常见构造函数 string类对象的容器操作 string类对象的访问及遍历操作 string类对象的修改操作 拓展 从本期开始,我们将正式学习C中的STL,美国的麦克阿瑟将军说过:“C不能没有STL就…

轻量封装WebGPU渲染系统示例<52>- Json数据描述材质、纹理等3D渲染场景信息

当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/feature/material/src/voxgpu/sample/DataDrivenScene3.ts 当前示例运行效果: ​​​​​​​ Json数据: {"renderer": {"mtplEnabled": true,"camera": {"eye&quo…

Linux实操——安装Mysql

安装Mysql 一、检查是否已经安装了mariadb数据库,并卸载二、下载mysql包,并通过ftp上传到服务器三、解压安装包四、创建数据存储文件夹五、创建执行mysqld命令的用户,并初始化mysql六、启用传输安全七、启动mysql,验证是否安装成功 总结 博主…

若依 ruoyi-vue3+ts-plus+ 宇道 yudao-ruoyi-vue-pro前端显示部门名称

想在 index.vue 上显示列表里对应的部门名称 效果 引入dept import * as DeptApi from "/api/system/dept"; 初始化时 /** 初始化 **/ onMounted(async () > {getList();deptNameList.value await DeptApi.getSimpleDeptList(); }) 加载id 对应的部门名称 …

威联通硬盘休眠后修改系统定时任务

按照网上一些教程,成功将威联通的机械硬盘设置了自动休眠。但是发现每天有多个整点硬盘会自动唤醒,怀疑是系统内置的定时任务触发了硬盘唤醒。 通过查看系统日志中事件和访问记录,判断出一些引发硬盘唤醒的自动任务,将这些定时任…

机器学习项目精选 第一期:超完整数据科学资料合集

大噶吼,不说废话,分享一波我最近看过并觉得非常硬核的资源,包括Python、机器学习、深度学习、大模型等等。 1、超完整数据科学资料合集 地址:https://github.com/krishnaik06/The-Grand-Complete-Data-Science-Materials Pytho…

【基础算法】试除法判定质数(优化)

文章目录 算法优化模板题目代码实现 算法优化模板 bool is_prime(int n){if(n < 2) return false;for(int i 2;i < n / i;i ){ //优化内容if(n % i 0){return false;}}return true; }注意这里的一个总要优化是for循环的终止条件是i<n/i。为什么不是i<n或者i<…

Java EE 网络之网络初识

文章目录 1. 网络发展史1.1 独立模式1.2 网络互连1.3 局域网 LAN1.4 广域网 WAN 2. 网络通信基础2.1 IP 地址2.2 端口号2.3 认识协议2.4 五元组2.5 协议分层2.5.1 什么是协议分层2.5.2 分层的作用2.5.3 OSI七层协议2.5.4 TCP/IP五层协议2.5.5 网络设备所在分层 2.6 分装和分用 …

10天玩转Python第9天:python 面向对象 全面详解与代码示例

今日内容 异常 模块和包 导入模块(导包)if __name__ "__main__": Unitest 框架的学习 了解, 基本组成 异常 异常传递[了解] 异常传递是 Python 中已经实现好了,我们不需要操作, 我们知道异常会进行传递. ​ 异常传递: 在函数嵌套调用的过程中, 被调用的函数 ,发…

获取MODIS的NDVI/EVI产品

目录 简介源代码运行流程参考博文 简介 本项目是使用MODIS的NDVI产品&#xff08;MOD13Q1&#xff09;,可获取从2000年至今的所有数据&#xff0c;更新频率为16天 MOD13Q1 V6.1产品以每像素为基础提供植被指数(VI)值。这里有两个主要的植被层。第一种是归一化植被指数(NDVI)&a…

LeedCode刷题---滑动窗口问题(二)

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C/C》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、将X减到0的最小操作数 题目链接&#xff1a;将 x 减到 0 的最小操作数 题目描述 给你一个整数数组 nums 和一个整数 x 。每一…

MetaAI语音翻译大模型Seamless登场,主打AI无缝同声传译

论文题目&#xff1a; Seamless: Multilingual Expressive and Streaming Speech Translation 论文链接&#xff1a; https://ai.meta.com/research/publications/seamless-multilingual-expressive-and-streaming-speech-translation/ 代码链接&#xff1a; GitHub - facebook…

2024年转行软件测试,报培训班3个月出来就是高薪工作,真的靠谱吗?

作为一个已在IT行业工作8年&#xff0c;分享一下我的经验&#xff0c;供大家参考。 讲真&#xff0c;现在想通过培训班培训几个月就进入IT行业&#xff0c;越来越来难了&#xff1b;如果是在2018年以前&#xff0c;还有机会&#xff0c;一方面&#xff0c;那个时候IT行业还不算…

Linux系统log日志简单清理

系统空间告急 清理log日志 找出当前目录中文件最大的10个文件&#xff1a; cd /var/log du -s ./* | sort -nr | head 系统日志log文件&#xff1a; ll -h /var/log/journal 只保留100MB的日志 journalctl --vacuum-size100M 系统暴力爆破SSH日志&#xff1a; ll -h /var/lo…