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 &section, const string &key, string &value, string &error);
bool ModifyValue(const string &section, const string &key, const string &value, string &error); private:
bool OpenFile();
bool FindSection(const string &sectionName);
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 &sectionName)
{
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 &section, 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 &section, 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++实现操作配置文件(告别跨平台问题)的更多相关文章

  1. 操作配置文件Properties

    // */ // ]]>   操作配置文件Properties Table of Contents 1 定义 2 读取配置值 3 修改和保存配置 4 注意 1 定义 csharp中在Settin ...

  2. day20 二十、加密模块、操作配置文件、操作shell命令、xml模块

    一.加密模块 1.hashlib模块:加密 ①有解密的加密方式 ②无解密的加密方式:碰撞检查 -- 1)不同数据加密后的结果一定不一致 -- 2)相同数据的加密结果一定是一致的 import hash ...

  3. 支持断线重连、永久watcher、递归操作并且能跨平台(.NET Core)的ZooKeeper异步客户端

    在公司内部的微服务架构中有使用到了"ZooKeeper",虽然官方有提供了.NET的SDK,但易用性非常的差,且搜遍github.nuget,没有发现一个可以跨平台且易用的组件,所 ...

  4. Java中Properties类的操作配置文件

    知识学而不用,就等于没用,到真正用到的时 候还得重新再学.最近在看几款开源模拟器的源码,里面涉及到了很多关于Properties类的引用,由于Java已经好久没用了,而这些模拟器大多用 Java来写, ...

  5. ASP.NET 操作配置文件

    1.配置文件的各种操作 http://www.cnblogs.com/shimeng3344518/archive/2007/04/23/723999.html 2. http://www.jb51. ...

  6. QSettings操作配置文件

    用Qt写界面时,难免会进行本地信息的保存,可以使用轻量级数据库sqlite,也可以使用QSettings读写配置文件.     如何来进行读写呢?如下,使用QSettings写一个通用的读写方法:   ...

  7. 使用纯生js操作cookie

    前段时间做项目的时候要使用js操作cookie,jquery也有相应的插件,不过还是觉得纯生的js比较好,毕竟不依赖jq. //获得coolie 的值 function cookie(name) { ...

  8. Python操作配置文件configparser模块

    在实际的开发过程中,我们常有操作ini格式和conf格式配置文件的操作,Python为我们提供了configparser模块,方便我们对配置文件进行读写操作. config.ini配置文件内容如下: ...

  9. kbmmw 中XML 操作入门(跨平台,而且可以与JSON,YAML,BSON 直接互相转换)

    delphi 很早以前就自带了xml 的操作,最新版里面有三种XML 解释器,一种是MSXML,看名字就知道 这个是微软自带的,这个据delphi 官方称是速度是最快的,但是只能在windows 上使 ...

随机推荐

  1. org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory'

    spring整合mybatis的时候,传统dao模式test报错 发现是在pojo类user对应的user.xml中配置路径写错了 org.springframework.beans.factory. ...

  2. 前端逼死强迫症系列之javascript续集

    一.javascript函数 1.普通函数 function func(){ } 2.匿名函数 setInterval(function(){ console.log(123); },5000) 3. ...

  3. ArrayUtils.

    String sfck=mp.get("SFCK")==null?"":mp.get("SFCK").toString();     Str ...

  4. 表单Content-Type为multipart/form-data时,后台数据的接收

    我们在写form提交表单的时候,后台大多数用request.getParameter的方式来接收前台输入的数据.但如果我们表单中提交的数据包含file文件传输的话,我们需要将Content-Type改 ...

  5. php - ftp 上传文件到远程服务器

    ccentos7服务器 ======================== 一.安装vsftpd及ftp命令 yum install vsftpd -y yum install ftp -y 二.vsf ...

  6. 如何准备算法工程师面试,斩获一线互联网公司机器学习岗offer?

    原文:https://zhuanlan.zhihu.com/p/76827460?utm_source=wechat_session&utm_medium=social&utm_oi= ...

  7. OpenJudge计算概论-年龄与疾病

    /*========================================================== 年龄与疾病 总时间限制: 1000ms 内存限制: 65536kB 描述 某医 ...

  8. bat 脚本之 使用函数

    bat 脚本之 使用函数 摘自:https://blog.csdn.net/peng_cao/article/details/73999076 2017年06月30日 15:06:37 pengcao ...

  9. Chrome浏览器控制网速的方法

  10. jmeter -- beanshell 执行本地py文件

    Process proc = Runtime.getRuntime().exec("python /Users/lucax/Desktop/工作/Ai双师项目/性能优化迭代_脚本准备/获取学 ...