C++实现INI文件读写

C++读写解析ini配置文件 支持解析ini文件支持修改、保存ini文件支持设置多个注释符,默认为“#”和’;’运行在Linux 下。 阅读详情

1. 概述

本文章主要参考这篇博客进行修改的,增加注释和修复了一些问题。这里给出完整的实现文件,在需要的地方包含该头文件就好了。

2. 实现

CMyINI.h
#pragma once
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <cstdlib>
#include <map>

using namespace std;

//INI文件结点存储结构
class ININode
{
public:
	ININode(string root, string key, string value)
	{
		this->root = root;
		this->key = key;
		this->value = value;
	}
	string root;
	string key;
	string value;
};

//键值对结构体
class SubNode
{
public:
	void InsertElement(string key, string value)
	{
		sub_node.insert(pair<string, string>(key, value));
	}
	map<string, string> sub_node;
};

//INI文件操作类
class CMyINI
{
public:
	CMyINI();
	~CMyINI();

public:
	int ReadINI(string path);													//读取INI文件
	string GetValue(string root, string key);									//由根结点和键获取值
	vector<ININode>::size_type GetSize(){ return map_ini.size(); }				//获取INI文件的结点数
	vector<ININode>::size_type SetValue(string root, string key, string value);	//设置根结点和键获取值
	int WriteINI(string path);			//写入INI文件
	void Clear(){ map_ini.clear(); }	//清空
	void Travel();						//遍历打印INI文件
private:
	map<string, SubNode> map_ini;		//INI文件内容的存储变量
};

CMyINI.cpp
#include "StdAfx.h"
#include "MyINI.h"

#define INIDEBUG

CMyINI::CMyINI()
{
}


CMyINI::~CMyINI()
{
}

//************************************************************************
// 函数名称:    	TrimString
// 访问权限:    	public 
// 创建日期:		2017/01/05
// 创 建 人:		
// 函数说明:		去除空格
// 函数参数: 	string & str	输入的字符串
// 返 回 值:   	std::string &	结果字符串
//************************************************************************
string &TrimString(string &str)
{
	string::size_type pos = 0;
	while (str.npos != (pos = str.find(" ")))
		str = str.replace(pos, pos + 1, "");
	return str;
}

//************************************************************************
// 函数名称:    	ReadINI
// 访问权限:    	public 
// 创建日期:		2017/01/05
// 创 建 人:		
// 函数说明:		读取INI文件,并将其保存到map结构中
// 函数参数: 	string path	INI文件的路径
// 返 回 值:   	int
//************************************************************************
int CMyINI::ReadINI(string path)
{
	ifstream in_conf_file(path.c_str());
	if (!in_conf_file) return 0;
	string str_line = "";
	string str_root = "";
	vector<ININode> vec_ini;
	while (getline(in_conf_file, str_line))
	{
		string::size_type left_pos = 0;
		string::size_type right_pos = 0;
		string::size_type equal_div_pos = 0;
		string str_key = "";
		string str_value = "";
		if ((str_line.npos != (left_pos = str_line.find("["))) && (str_line.npos != (right_pos = str_line.find("]"))))
		{
			//cout << str_line.substr(left_pos+1, right_pos-1) << endl;
			str_root = str_line.substr(left_pos + 1, right_pos - 1);
		}

		if (str_line.npos != (equal_div_pos = str_line.find("=")))
		{
			str_key = str_line.substr(0, equal_div_pos);
			str_value = str_line.substr(equal_div_pos + 1, str_line.size() - 1);
			str_key = TrimString(str_key);
			str_value = TrimString(str_value);
			//cout << str_key << "=" << str_value << endl;
		}

		if ((!str_root.empty()) && (!str_key.empty()) && (!str_value.empty()))
		{
			ININode ini_node(str_root, str_key, str_value);
			vec_ini.push_back(ini_node);
			//cout << vec_ini.size() << endl;
		}
	}
	in_conf_file.close();
	in_conf_file.clear();

	//vector convert to map
	map<string, string> map_tmp;
	for (vector<ININode>::iterator itr = vec_ini.begin(); itr != vec_ini.end(); ++itr)
	{
		map_tmp.insert(pair<string, string>(itr->root, ""));
	}	//提取出根节点
	for (map<string, string>::iterator itr = map_tmp.begin(); itr != map_tmp.end(); ++itr)
	{
#ifdef INIDEBUG
		cout << "根节点: " << itr->first << endl;
#endif	//INIDEBUG
		SubNode sn;
		for (vector<ININode>::iterator sub_itr = vec_ini.begin(); sub_itr != vec_ini.end(); ++sub_itr)
		{
			if (sub_itr->root == itr->first)
			{
#ifdef INIDEBUG
				cout << "键值对: " << sub_itr->key << "=" << sub_itr->value << endl;
#endif	//INIDEBUG
				sn.InsertElement(sub_itr->key, sub_itr->value);
			}
		}
		map_ini.insert(pair<string, SubNode>(itr->first, sn));
	}
	return 1;
}

//************************************************************************
// 函数名称:    	GetValue
// 访问权限:    	public 
// 创建日期:		2017/01/05
// 创 建 人:		
// 函数说明:		根据给出的根结点和键值查找配置项的值
// 函数参数: 	string root		配置项的根结点
// 函数参数: 	string key		配置项的键
// 返 回 值:   	std::string		配置项的值
//************************************************************************
string CMyINI::GetValue(string root, string key)
{
	map<string, SubNode>::iterator itr = map_ini.find(root);
	map<string, string>::iterator sub_itr = itr->second.sub_node.find(key);
	if (!(sub_itr->second).empty())
		return sub_itr->second;
	return "";
}

//************************************************************************
// 函数名称:    	WriteINI
// 访问权限:    	public 
// 创建日期:		2017/01/05
// 创 建 人:		
// 函数说明:		保存XML的信息到文件中
// 函数参数: 	string path	INI文件的保存路径
// 返 回 值:   	int
//************************************************************************
int CMyINI::WriteINI(string path)
{
	ofstream out_conf_file(path.c_str());
	if (!out_conf_file)
		return -1;
	//cout << map_ini.size() << endl;
	for (map<string, SubNode>::iterator itr = map_ini.begin(); itr != map_ini.end(); ++itr)
	{
		//cout << itr->first << endl;
		out_conf_file << "[" << itr->first << "]" << endl;
		for (map<string, string>::iterator sub_itr = itr->second.sub_node.begin(); sub_itr != itr->second.sub_node.end(); ++sub_itr)
		{
			//cout << sub_itr->first << "=" << sub_itr->second << endl;
			out_conf_file << sub_itr->first << "=" << sub_itr->second << endl;
		}
	}

	out_conf_file.close();
	out_conf_file.clear();

	return 1;
}


//************************************************************************
// 函数名称:    	SetValue
// 访问权限:    	public 
// 创建日期:		2017/01/05
// 创 建 人:		
// 函数说明:		设置配置项的值
// 函数参数: 	string root		配置项的根节点
// 函数参数: 	string key		配置项的键
// 函数参数: 	string value	配置项的值
// 返 回 值:   	std::vector<ININode>::size_type	
//************************************************************************
vector<ININode>::size_type CMyINI::SetValue(string root, string key, string value)
{
	map<string, SubNode>::iterator itr = map_ini.find(root);	//查找
	if (map_ini.end() != itr)
	{
		//itr->second.sub_node.insert(pair<string, string>(key, value));
		itr->second.sub_node[key] = value;
	}	//根节点已经存在了,更新值
	else
	{
		SubNode sn;
		sn.InsertElement(key, value);
		map_ini.insert(pair<string, SubNode>(root, sn));
	}	//根节点不存在,添加值

	return map_ini.size();
}

//************************************************************************
// 函数名称:    	Travel
// 访问权限:    	public 
// 创建日期:		2017/01/05
// 创 建 人:		
// 函数说明:		遍历打印INI文件
// 返 回 值:   	void
//************************************************************************
void CMyINI::Travel()
{
	for (map<string, SubNode>::iterator itr = this->map_ini.begin(); itr!= this->map_ini.end(); ++itr)
	{
		//root
		cout << "[" << itr->first << "]" << endl;
		for (map<string, string>::iterator itr1=itr->second.sub_node.begin(); itr1!=itr->second.sub_node.end();
			++itr1)
		{
			cout << "    " << itr1->first << " = " << itr1->second << endl;
		}
	}
	
}
测试之前INI文件的内容:
测试程序:
	CMyINI *p = new CMyINI();
	p->ReadINI("Setting.ini");
	cout << "\n原始INI文件内容:" << std::endl;
	p->Travel();
	p->SetValue("setting", "hehe", "eheh");
	cout << "\n增加节点之后的内容:" << std::endl;
	p->Travel();
	cout << "\n修改节点之后的内容:" << std::endl;
	p->SetValue("kk", "kk", "2");
	p->Travel();
	p->WriteINI("Setting.ini");
测试结果:



【UE】C++与蓝图协作:实现动态配置的INI文件读写方案 本文详细介绍了在虚幻引擎(UE)中通过C++与蓝图协作实现动态配置INI文件读写方案。文章从配置文件的重要性出发,逐步讲解如何创建BlueprintFunctionLibrary、实现多配置文件支持及数据类型扩展,并分享打包部署的注意事项和最佳实践,帮助开发者高效管理游戏配置数据。 阅读详情

相关推荐

C++ INI文件读写实现:从设计到源码的完整指南

配置文件是软件工程中管理程序行为和数据的关键机制,其核心原理在于将可变参数与代码逻辑分离,实现灵活部署与动态调整。在众多配置格式中,INI文件以其结构简单、零依赖和极低解析开销的技术价值,在C++桌面应用、游戏及嵌入式系统等场景中保持着独特的生命力。本文聚焦于C++标准库未提供原生支持的INI文件解析,深入探讨如何设计一个健壮、易用的INI读写器类。通过拆解文件I/O、字符串处理、数据结构选型(如嵌套std::map)及类型安全转换等关键实现细节,并融入对线程安全、编码问题和常见陷阱的工程实践分析,最终提供

weixin_34094282的博客 294

C++ 读写ini文件

C++读写ini文件封装成类,直接创建对象对ini文件进行读写操作,真实有效 ,可以联系我 关注:https://blog.csdn.net/qq_34510308

C++实现INI文件读写:轻量级跨平台配置管理库设计与实践

在软件工程中,配置文件管理是基础且关键的技术环节,它决定了应用程序的灵活性和可维护性。其核心原理是通过持久化存储程序运行参数,实现行为的外部化控制。从技术价值看,优秀的配置管理方案能提升开发效率、增强系统可配置性,并简化部署流程。常见的应用场景包括游戏设置、服务端参数、用户偏好存储等。本文聚焦于INI文件这一经典格式,它凭借结构清晰、人类可读的特点,在众多场景中仍具实用价值。针对跨平台开发中Windows API的局限性,我们深入探讨了如何用纯C++实现一个轻量级、头文件式的INI读写库,重点解析了其基于节

weixin_29215391的博客 295

C++读写INI文件

本文介绍了如何使用C++代码读取和写入INI文件。通过使用Windows API函数,我们可以轻松地完成这些任务。如果您需要在自己的应用程序中使用INI文件存储配置信息,那么我们希望上面的代码能为您提供有用的参考。INI文件是一种文本文件,通常用于存储程序配置信息。在C++中读取和写入INI文件是一项非常常见的任务。接下来,我将介绍如何使用C++代码读取和写入INI文件。接下来,我们将演示如何使用C++代码将数据写入INI文件。首先,我们需要一个INI文件C++读写INI文件

DevForge的博客 835

读写ini配置文件C++

读写ini配置文件C++

NRWHF的博客 9364

C++读写ini文件

一般的ini配置文件由节、键、值组成。 【参数】(键=值),例如 :key=value; 【节】:所有的参数都是以节(section)为单位结合在一起的。所有的section名称都是独占一行,并且section名字都被方括号包围着([XXX])。在section声明后的所有parameters都属于该section。 例如:[section1] 所以一个包含节,键,值的简单ini配置文件,例如: [port] portName=port1 port=123 1.使用INIReader.h头文件 1.IN

weixin_43229348的博客 7229

C++ 实现INI文件读写

在某些情况下,第三方库可能无法满足特定的需求,因此需要自定义构建配置文件库。构建高级配置文件库可按以下步骤进行:定义配置模型:创建用于表示配置数据的类和结构。实现配置解析器:编写解析器来处理不同格式的配置文件。配置加载和保存:实现配置的加载和保存机制,支持动态和静态配置项。集成到应用程序:将配置库集成到应用程序中,并提供API供其他模块使用。下面是一个简单的自定义配置文件实现示例(伪代码):public:// 加载配置文件

weixin_42351520的博客 606

windows C/C++ 实现ini文件读写

实现ini配置文件读写操作,以及获取程序路径 ini格式稍微来说比较简单为: [Tiatle] 字段1=内容 字段2=内容 内容为纯数字时,可以使用整形(int)方式读取,如果是字符串则需使用字符串(string)读取,部分代码需要用到Windows API 所以需加上windows.h头文件 使用多字节编码代码如下: 1、获取程序路径: //获取程序路径 char* GetAppPath(char *AppPath,int nSize) { int i; memset(AppPath,0,nSize)

Feng的博客 4660

C++实现INI配置文件读写完整源码解析

TinyIni 是一个轻量级的 C++ 配置文件解析库,专为处理 INI 格式文件而设计。它以极简的接口和高效的解析能力受到开发者的青睐。TinyIni 的源码结构非常清晰,通常只需要一个头文件(如tinyini.h)和一个源文件(如),就可以轻松集成到项目中。优势:轻量高效:无外部依赖,编译速度快。跨平台支持:适用于 Windows、Linux 和 macOS。简单易用 API:提供getset等方法,便于读写配置项。

weixin_29717341的博客 924

c++ 标准库读写 ini 文件

下面是一个完整的 INI 文件类的实现,包括读取和写入 INI 文件的功能。

u013798595的博客 1097

C++ INI文件读写实现:从原理到工程实践

配置文件是软件工程中管理程序行为和数据的关键机制,其核心原理在于将可变的参数与代码逻辑分离,实现灵活部署。在众多配置格式中,INI文件以其结构简单、易于阅读和编辑的特点,在轻量级应用、遗留系统维护及快速原型开发中占据一席之地。其技术价值在于提供了一种极低开销、不依赖复杂第三方库的配置管理方案,尤其适合对启动速度或二进制体积有严格要求的C++项目。从应用场景看,无论是游戏客户端的设置保存、服务端程序的参数调整,还是嵌入式设备的参数存储,INI文件都能胜任。本文将聚焦于C++实现,深入探讨如何设计健壮的INI

人生的意義在於修煉!修煉之路~ 489

C++实现ini文件读写(Linux和Windows平台均可运行)

C++实现ini文件读写(Linux和Windows平台均可运行) 去发现同类优质开源项目:https://gitcode.com/ 简介 本资源文件提供了一个用C++实现ini文件读写功能,该功能可以在Windows和Linux平台上运行。代码简洁易懂,适合初学者学习和借鉴。 功能特点 跨平台支持:代码可以在Windows和Linux操作系统上无缝运行。 简单易用:提供了基本的ini文件读写...

gitblog_09703的博客 428

C/C++ 实现INI配置文件读写

INI文件是一种标准的Windows平台配置文件,通常这种配置文件用于保存系统软件的一些基本配置参数,如下代码是本人从网络上收集到的一段纯C++编写的配置解析代码,感觉使用起来很方便,所以放到这里分享一下。

微软技术分享 9504

C++ INI配置文件读写库:工业级封装的设计与实现

C++项目开发中,配置文件管理是连接代码逻辑与运行环境的关键环节。其核心原理在于将可变参数从硬编码中解耦,通过外部文件实现动态配置,从而提升软件的灵活性和可维护性。INI文件因其结构简单、易于阅读和编辑,成为轻量级配置的经典选择。一个健壮的INI解析库不仅能高效处理节、键、值的读写,更能通过内存缓存、线程安全、强异常处理等工程化设计,为应用提供稳定可靠的基础设施支持。本文聚焦于C++ INI库的工业级封装,深入探讨如何通过模板化接口、脏标记优化、编码处理等关键技术,构建一个功能完备、性能优异且零依赖的解决

weixin_33698823的博客 449

C++ INI配置文件读写源码解析:从零实现跨平台配置管理

配置文件是软件工程中管理应用参数和设置的核心机制,其本质是将程序的可变数据与代码逻辑分离,实现灵活配置。INI格式作为一种经典的配置文件格式,因其结构简单、可读性强,在游戏开发、服务器配置和桌面应用等场景中广泛应用。其技术价值在于提供了一种轻量级、易于人工编辑和机器解析的数据持久化方案。通过理解键值对(Key-Value Pair)和节(Section)的组织原理,开发者可以构建健壮的配置管理系统。本文聚焦于C++标准库实现,深入剖析了如何利用文件流(fstream)和字符串处理,打造一个不依赖第三方库、代

weixin_33704591的博客 404

C++版:一个.h文件实现读写ini文件

文件在此下载: 使用范例 // simple demonstration CSimpleIniA ini; ini.SetUnicode(); SI_Error rc = ini.LoadFile("example.ini"); if (rc < 0) { /* handle error */ }; ASSERT_EQ(rc, SI_OK); const char* pv; pv = ini.GetValue("section", "key", "default"); A

QQ6550523的博客 652

C/C++编程:windows C/C++ 实现ini文件读写

ini格式稍微来说比较简单为: [Tiatle] 字段1=内容 字段2=内容 内容为纯数字时,可以使用整形(int)方式读取,如果是字符串则需使用字符串(string)读取,部分代码需要用到Windows API 所以需加上windows.h头文件 使用多字节编码代码如下 1、获取程序路径 //获取程序路径 char* GetAppPath(char *AppPath,int nSize) { int i; memset(AppPath,0,nSize); #ifdef UNICODE GetModu

OceanStar的博客 1075
上一篇: VS下TinyXml使用
下一篇: Leetcode——1. Two Sum
m_buddy
m_buddy 领域专家: 人工智能技术领域 领域专家: 人工智能技术领域
博客等级 码龄11年 2354粉丝 551原创
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值