1. 程式人生 > 其它 >C++實現INI檔案讀寫

C++實現INI檔案讀寫

C++實現INI檔案讀寫

https://blog.csdn.net/m_buddy/article/details/54097131

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

  

測試結果: