纯C++实现操作配置文件(告别跨平台问题)
CConfig.h
#ifndef _CCONFIG_H
#define _CCONFIG_H
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
using namespace std;
class CConfig
{
public:
CConfig();
~CConfig();
void SetFilePath(const string &filePath);
string GetFilePath();
bool GetValue(const string §ion, const string &key, string &value, string &error);
bool ModifyValue(const string §ion, const string &key, const string &value, string &error);
private:
bool OpenFile();
bool FindSection(const string §ionName);
bool FindKey(const string &key);
bool OpenFileRead();
bool OpenFileWrite();
bool SetValue(const string &key, const string &value);
void WriteFile(vector<string> &vContent);
string m_filePath;
fstream m_fout;
fstream m_fin;
string m_content;
string m_value;
string m_error;
};
#endif
CConfig.cpp
/********************************************************
Copyright (C), 2016-2018,
FileName: CConfig
Author: woniu201
Created: 2018/11/16
Description: 纯C++实现配置文件的操作
********************************************************/
#include "CConfig.h"
CConfig::CConfig()
{
}
CConfig::~CConfig()
{
}
/************************************
@ Brief: 设置配置文件路径
@ Author: woniu201
@ Created: 2018/12/21
@ Return:
************************************/
void CConfig::SetFilePath(const string &filePath)
{
m_filePath = filePath;
}
/************************************
@ Brief: 读取配置文件路径
@ Author: woniu201
@ Created: 2018/12/21
@ Return:
************************************/
string CConfig::GetFilePath()
{
return this->m_filePath;
}
/************************************
@ Brief: 打开配置文件
@ Author: woniu201
@ Created: 2018/12/21
@ Return:
************************************/
bool CConfig::OpenFile()
{
if (true == m_fin.is_open())
{
m_fin.close();
}
m_fin.open(m_filePath.c_str());
if (!m_fin.is_open())
{
m_error = "open file fail:" + m_filePath;
return false;
}
return true;
}
/************************************
@ Brief: 找节名
@ Author: woniu201
@ Created: 2018/12/21
@ Return:
************************************/
bool CConfig::FindSection(const string §ionName)
{
if (-1 != m_content.find('['))
{
string sTemp = m_content.substr(m_content.find('[') + 1, m_content.find(']') - m_content.find('[') - 1);
if (0 == strcmp(sTemp.c_str(), sectionName.c_str()))
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
/************************************
@ Brief: 找键名
@ Author: woniu201
@ Created: 2018/12/21
@ Return:
************************************/
bool CConfig::FindKey(const string &key)
{
size_t iDelePlace = m_content.find((char)'//', 0);
size_t iFindEqual = m_content.find((char)'=', 0);
//被注释的行,或者是包含key但是已经被注视掉了,过滤
if ((-1 != iDelePlace && iDelePlace < iFindEqual) || (-1 != iDelePlace && -1 == iFindEqual) || -1 == iFindEqual)
{
return false;
}
string sKey = m_content.substr(0, m_content.find('='));
if (0 == strcmp(sKey.c_str(), key.c_str()))
{
m_value = m_content.substr(m_content.find('=') + 1, m_content.length() - m_content.find('=') - 1);
return true;
}
return false;
}
/************************************
@ Brief: 读取节下Key对应的value值
@ Author: woniu201
@ Created: 2018/12/21
@ Return:
************************************/
bool CConfig::GetValue(const string §ion, const string &key, string &value, string &error)
{
m_error = "";
if (false == OpenFile())
{
error = m_error;
return false;
}
char str[4096] = { 0 };
bool bFindSection = false;
while (m_fin.getline(str, sizeof(str)))
{
m_content = str;
if (!bFindSection)
{
if (FindSection(section))
{
bFindSection = true;
}
else
{
m_error = "";
m_error = "节点" + section + "不存在";
}
}
else
{
if (FindKey(key))
{
m_fin.close();
m_error = "";
value = m_value;
return true;
}
else
{
m_error = "";
m_error = "键名" + key + "不存在";
}
}
memset(str, 0, 4096);
}
error = m_error;
m_fin.close();
return false;
}
/************************************
@ Brief: 读的方式打开文件
@ Author: woniu201
@ Created: 2018/12/21
@ Return:
************************************/
bool CConfig::OpenFileRead()
{
m_fout.close();
//关闭后要在清空一下,否则下次打开会出错
m_fout.clear();
m_fout.open(m_filePath.c_str(), ios::in);
if (!m_fout.is_open())
{
m_error = "open file fail:" + m_filePath;
return false;
}
return true;
}
/************************************
@ Brief: 写的方式打开文件
@ Author: woniu201
@ Created: 2018/12/21
@ Return:
************************************/
bool CConfig::OpenFileWrite()
{
m_fout.close();
//关闭后要在清空一下,否则下次打开会出错
m_fout.clear();
m_fout.open(m_filePath.c_str(), ios::out | ios::trunc);
if (!m_fout.is_open())
{
m_error = "can not open file " + m_filePath;
return false;
}
return true;
}
/************************************
@ Brief: 找KEY,设置新值
@ Author: woniu201
@ Created: 2018/12/21
@ Return:
************************************/
bool CConfig::SetValue(const string &key, const string &value)
{
size_t iDelePlace = m_content.find((char)'//');
size_t iFindEqual = m_content.find((char)'=');
//被注释的行,或者是包含key但是已经被注视掉了,过滤
if ((-1 != iDelePlace && iDelePlace < iFindEqual) || (-1 != iDelePlace && -1 == iFindEqual) || -1 == iFindEqual)
{
return false;
}
string sKey = m_content.substr(0, m_content.find('='));
if (0 == strcmp(sKey.c_str(), key.c_str()))
{
m_content = m_content.substr(0, m_content.find('=') + 1) + value;
return true;
}
return false;
}
/************************************
@ Brief: 修改配置文件KEY对应的value
@ Author: woniu201
@ Created: 2018/12/21
@ Return:
************************************/
bool CConfig::ModifyValue(const string §ion, const string &key, const string &value, string &error)
{
m_error = "";
if (false == OpenFileRead())
{
error = m_error;
return false;
}
char str[4096] = { 0 };
vector<string> vContent;
bool isModify = false;
bool isFindSection = false;
while ( (m_fout.getline(str, sizeof(str))))
{
m_content = str;
if (!isFindSection)
{
if (FindSection(section))
{
isFindSection = true;
}
else
{
m_error = "";
m_error = "节点" + section + "不存在";
}
}
else
{
if (!isModify)
{
if (SetValue(key, value))
{
isModify = true;
}
else
{
m_error = "";
m_error = "键名" + key + "不存在";
}
}
}
vContent.push_back(m_content);
m_content = "";
memset(str, 0, 4096);
}
error = m_error;
WriteFile(vContent);
m_fout.flush();
m_fout.close();
return isModify;
}
/************************************
@ Brief: 写文件
@ Author: woniu201
@ Created: 2018/12/21
@ Return:
************************************/
void CConfig::WriteFile(vector<string> &vContent)
{
if (false == OpenFileWrite())
{
m_fout.close();
return;
}
for (size_t iIndex = 0; iIndex < vContent.size(); iIndex++)
{
m_fout << vContent[iIndex] << endl;
}
m_fout.close();
vector<string>().swap(vContent);
}
main.cpp
#include "CConfig.h"
int main()
{
CConfig config;
config.SetFilePath("a.ini");
string value = "";
string error = "";
config.GetValue("ServerUrl", "PcName", value, error);
cout << value << endl;
cout << error << endl;
error = "";
config.ModifyValue("ServerUrl", "PcName", "5.0", error);
cout << error << endl;
getchar();
}
配置文件a.ini内容如下:


纯C++实现操作配置文件(告别跨平台问题)的更多相关文章
- 操作配置文件Properties
// */ // ]]> 操作配置文件Properties Table of Contents 1 定义 2 读取配置值 3 修改和保存配置 4 注意 1 定义 csharp中在Settin ...
- day20 二十、加密模块、操作配置文件、操作shell命令、xml模块
一.加密模块 1.hashlib模块:加密 ①有解密的加密方式 ②无解密的加密方式:碰撞检查 -- 1)不同数据加密后的结果一定不一致 -- 2)相同数据的加密结果一定是一致的 import hash ...
- 支持断线重连、永久watcher、递归操作并且能跨平台(.NET Core)的ZooKeeper异步客户端
在公司内部的微服务架构中有使用到了"ZooKeeper",虽然官方有提供了.NET的SDK,但易用性非常的差,且搜遍github.nuget,没有发现一个可以跨平台且易用的组件,所 ...
- Java中Properties类的操作配置文件
知识学而不用,就等于没用,到真正用到的时 候还得重新再学.最近在看几款开源模拟器的源码,里面涉及到了很多关于Properties类的引用,由于Java已经好久没用了,而这些模拟器大多用 Java来写, ...
- ASP.NET 操作配置文件
1.配置文件的各种操作 http://www.cnblogs.com/shimeng3344518/archive/2007/04/23/723999.html 2. http://www.jb51. ...
- QSettings操作配置文件
用Qt写界面时,难免会进行本地信息的保存,可以使用轻量级数据库sqlite,也可以使用QSettings读写配置文件. 如何来进行读写呢?如下,使用QSettings写一个通用的读写方法: ...
- 使用纯生js操作cookie
前段时间做项目的时候要使用js操作cookie,jquery也有相应的插件,不过还是觉得纯生的js比较好,毕竟不依赖jq. //获得coolie 的值 function cookie(name) { ...
- Python操作配置文件configparser模块
在实际的开发过程中,我们常有操作ini格式和conf格式配置文件的操作,Python为我们提供了configparser模块,方便我们对配置文件进行读写操作. config.ini配置文件内容如下: ...
- kbmmw 中XML 操作入门(跨平台,而且可以与JSON,YAML,BSON 直接互相转换)
delphi 很早以前就自带了xml 的操作,最新版里面有三种XML 解释器,一种是MSXML,看名字就知道 这个是微软自带的,这个据delphi 官方称是速度是最快的,但是只能在windows 上使 ...
随机推荐
- java file 常用操作
File file = new File("D:\\javaClass\\image"); // 测试此抽象路径名表示的文件或目录是否存在. // 当且仅当此抽象路径名表示的文件或 ...
- 命令行中生成 md5、sha1、sha256 校验和
在测试过程中有时候需要对某个文件Hash值进行校验,如接口返回一个文件下载地址及hash值,那么除了对比平台端展示和接口下发是否一至,还有一个办法就是命令行使用相关命令 1.Window 注:我是在g ...
- hive --metastore三种模式
在官网上对于这几种模式的介绍如下: 按Metastore数据库位置分: 1.本地/嵌入式Metastore数据库(Derby) 2.远程Metastore数据库(其他的关系型数据库,像mysql.or ...
- Mybatis使用IN语句查询
一.简介 在SQL语法中如果我们想使用in的话直接可以像如下一样使用: select * from HealthCoupon where useType in ( '4' , '3' ) 但是如果在M ...
- 2018-2019-2 网络对抗技术 20165231 Exp9 Web安全基础
实验内容 本实践的目标理解常用网络攻击技术的基本原理,做不少于7个题目,共3.5分.包括(SQL,XSS,CSRF).Webgoat实践下相关实验. 实验过程 WebGoat: Webgoat是OWA ...
- 基于docker部署zabbix
基础环境 cat /etc/redhat-release CentOS Linux release (Core) docker安装 配置yum源 # vim /etc/yum.repos.d/dock ...
- python 设计模式之备忘录模式
1.为什么用备忘录模式 假设大战僵尸游戏共10关,越是往后关卡越难,越难就越是费时间费钱费精力. 开始大战僵尸,玩了好久好久终于玩到了第9关,真是不容易. 这个时候开始玩第9关了,哇,好难啊,真不幸, ...
- SQL-W3School-高级:SQL 数据库
ylbtech-SQL-W3School-高级:SQL 数据库 1.返回顶部 1. 现代的 SQL 服务器构建在 RDBMS 之上. DBMS - 数据库管理系统(Database Managemen ...
- 重装GUI前备份GUI配置
sap系统要重装, gui配置 想要保存,这个要怎么弄? SAP菜单 选项-> 本地数据 -> 历史记录 里的地址 C:\Users\Administrator\AppData\Roam ...
- mysql常用命令、非交互式mysql命令看29条
CentOS下mysql数据库常用命令总结1.更改root密码 mysqladmin -uroot password 'yourpassword' 2.远程登陆mysql服务器 mysql -uroo ...