C++实现INI文件读写
2023-09-11 14:22:29 时间
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");
测试结果:
相关文章
- 解决JAVA调用C++ DLL文件Unable to load library的问题
- C++实现读写文件
- Win10系列:VC++ XML文件解析
- VC++_错误 无法打开包括文件“glglut.h” No such file or directory 怎么办
- C/C++读写文件
- 【转】C++调用Matlab的.m文件
- c++文件操作3之二进制写文件
- atitit.软件开发GUI 布局管理优缺点总结java swing wpf web html c++ qt php asp.net winform
- 设计模式C++实现——外观模式
- 【华为OD机试 2023最新 】 机房布局(C++ 100%)
- 解答私信@被c++折磨头秃的花季美少女 //C++ 编写一个进阶版的进制转换程序,运行功能如下:请选择要输入的数字的进制(2、8、10、16):请输入该数字:请选择要转换成的进制(2、8。。。
- C++文件流fstream相关操作
- C++ 数组中出现次数超过一半的数字
- c++ vector 初始化_C++--vector()的用法
- AI模型C++部署:ubuntu安装Cython并使用C/C++调用python动态库【附加c++与python互相调用算法demo程序接口的源码】
- C++输入输出类的层次
- C++ map键值对容器demo(四十六)
- C++读写文件之在Json数组追加元素(二十八)
- vc++实现avi文件的操作
- VC++给软件添加异常捕获模块生成dump文件(附源码)
- VC++使用fprintf函数实现写日志文件的功能(附源码)
- VC++计算文件和文件夹的大小(附源码)
- VC++实现打开文件和打开所在文件夹的功能(附源码)
- VC++中实现INI文件读写的方法和示例
- C++基础知识要点--语句(Primer C++ 第五版 · 阅读笔记)
- C/C++ MySQL API
- 单链表的逆置-C++实现(五十四)
- 基于C++的Winograd卷积实现(分片+乒乓)