C++实现INI文件读写

161次阅读
没有评论

共计 6137 个字符,预计需要花费 16 分钟才能阅读完成。

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;
    }
  }
  
}

测试程序:

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");

 

正文完
 
admin
版权声明:本站原创文章,由 admin 2022-01-04发表,共计6137字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)
验证码