.ini配置文件的寫法

今天有需要寫一個ini配置文件,我之前一直沒弄過,後來上網查了一下,一共有兩種方法,一種是windows api提供了兩個函數,一種是自己手搓的文件讀寫。

先來看看win api的吧,因爲比較簡單:

BOOL WritePrivateProfileString(  
  LPCTSTR lpAppName,  // INI文件中的一個字段名[節名]可以有很多個節名  
  
  LPCTSTR lpKeyName,  // lpAppName 下的一個鍵名,也就是裏面具體的變量名  
  
  LPCTSTR lpString,   // 鍵值,也就是數據  
  
  LPCTSTR lpFileName  // INI文件的路徑  
);  

DWORD GetPrivateProfileString(  
  LPCTSTR lpAppName,        // INI文件中的一個字段名[節名]可以有很多個節名  
  
  LPCTSTR lpKeyName,        // lpAppName 下的一個鍵名,也就是裏面具體的變量名  
  
  LPCTSTR lpDefault,        // 如果lpReturnedString爲空,則把個變量賦給lpReturnedString  
  
  LPTSTR lpReturnedString,  // 存放鍵值的指針變量,用於接收INI文件中鍵值(數據)的接收緩衝區  
  
  DWORD nSize,            // lpReturnedString的緩衝區大小  
  
  LPCTSTR lpFileName        // INI文件的路徑  
);  

下面是我師傅給我的資料,手搓的,脫離winapi,雖然我覺得並沒什麼卵用,我還是用了上面的方法。

iniFile.h

#ifndef __INI_FILE_H__
#define __INI_FILE_H__

#include <map>
#include <string>
#include <iostream>

class CIniFile
{
public:
	CIniFile();
	~CIniFile();

	void SetFile(std::string filename);
	int ReadInteger(std::string selection, std::string key, int defvalue = 0);
	void WriteInteger(std::string selection, std::string key, int value);
	std::string ReadString(std::string selection, std::string key, std::string defvalue = "");
	void WriteString(std::string selection, std::string key, std::string value);
	double ReadDouble(std::string selection, std::string key, double defvalue = 0.0f);
	void WriteDouble(std::string selection, std::string key, double value);
	bool ReadBoolean(std::string selection, std::string key, bool defvalue = false);
	void WriteBoolean(std::string selection, std::string key, bool value);
public:
	bool Load(int &errLine);
	void Dump(std::ostream &);
	void Save();
protected:
	static const std::string GROUP_DEFAULT;
	static void trimString(std::string &str);
	std::string get(std::string selection, std::string key);
	void set(std::string selection, std::string key, std::string value);
private:
	std::string pathname;
	typedef std::map<std::string, std::string, std::greater<std::string> > Pairs;
	Pairs pairs;
	std::map<std::string, Pairs, std::greater<std::string> > paragraph;
private:
	bool modifyed;
};

#endif

iniFile.cpp

#include "IniFile.h"
#include <fstream>
#include <ctype.h>
#include <sstream>
#include <iostream>

const std::string CIniFile::GROUP_DEFAULT("default");

CIniFile::CIniFile() : modifyed(false)
{
}

CIniFile::~CIniFile()
{
	if (modifyed)
	{
		Save();
	}
}

void CIniFile::SetFile(std::string filename)
{
	pathname = filename;
}

void CIniFile::trimString(std::string &str)
{
	int i = 0;
	for(; i < (int)str.length() && isspace(str[i]); i++);

	str = str.substr(i);

	for(i = (int)str.length() - 1; i >= 0 && isspace(str[i]); i--);
	str.erase(i + 1);

}

bool CIniFile::Load(int &errLine)
{
	std::ifstream in(pathname.c_str());
	std::string value;
	paragraph.clear();
	errLine = 0;
	std::string currentGroup = GROUP_DEFAULT;
	Pairs pairs;
	while(std::getline(in, value))
	{
		errLine++;
		trimString(value);
		if(value[0] == '#')
			continue;

		if(value.length() == 0)
			continue;
		std::string::size_type idx = value.find("=");
		if(idx == std::string::npos)
		{
			if(value[0] == '[' && value[value.length() - 1] == ']')
			{
				value.erase(value.length() - 1);
				value.erase(0, 1);

				paragraph[currentGroup] = pairs;
				currentGroup = value;
				pairs.clear();
			} else
				return false;
		}
		else
		{
			std::string key = value.substr(0, idx);
			trimString(key);

			std::string val, tmpval = value.substr(idx + 1);
			std::string::size_type idx1 = tmpval.find("#"); //'#' for comment

			if (idx1 != std::string::npos)
			{
				val = tmpval.substr(0, idx1);
			}
			else
			{
				val = tmpval;
			}
			trimString(val);
			pairs[key] = val;
		}
	}

	paragraph[currentGroup] = pairs;
	return true;
} 

bool CIniFile::ReadBoolean(std::string selection, std::string key, bool defvalue)
{
	bool val = defvalue;
	std::string value = get(selection, key);
	if (value.length()>0)
	{
		if (value == std::string("true"))
		{
			val = true;
		}
		else
		{
			val = false;
		}
	}
	return val;
}

void CIniFile::WriteBoolean(std::string selection, std::string key, bool value)
{
	std::string str_value = (value ? "true" : "false");
	WriteString(selection, key, str_value);
}

double CIniFile::ReadDouble(std::string selection, std::string key, double defvalue)
{
	double val = defvalue;
	std::string value = get(selection, key);
	if (value.length()>0)
	{
		std::istringstream in(value);
		in >> val; 
	}
	return val;
}

void CIniFile::WriteDouble(std::string selection, std::string key, double value)
{
	std::ostringstream os;
	os << value;

	WriteString(selection, key, os.str());
}

int CIniFile::ReadInteger(std::string selection, std::string key, int defvalue)
{
	int val = defvalue;
	std::string value = get(selection, key);
	if (value.length()>0)
	{
		std::istringstream in(value);
		in >> val; 
	}
	return val;
}

void CIniFile::WriteInteger(std::string selection, std::string key, int value)
{
	std::ostringstream os;
	os << value;
	WriteString(selection, key, os.str());
}

std::string CIniFile::ReadString(std::string selection, std::string key, std::string defvalue)
{
	std::string value = get(selection, key);
	return (value.length()>0 ? value : defvalue);
}

void CIniFile::WriteString(std::string selection, std::string key, std::string value)
{
	set(selection, key, value);
}
void CIniFile::Dump(std::ostream &os)
{
	//dump DEFAULT_GROUP group first

	Pairs pairs = paragraph[GROUP_DEFAULT];
	Pairs::iterator p = pairs.begin();
	for(; p != pairs.end(); ++p)
	{
		os << p->first << '=' << p->second << std::endl;
	}
	std::map<std::string, Pairs, std::greater<std::string> >::iterator pos = paragraph.begin();

	for(; pos != paragraph.end(); ++pos)
	{
		pairs = pos->second;
		if(pos->first == GROUP_DEFAULT)
			continue;
		os << '[' << pos->first << ']' << std::endl;
		p = pairs.begin();
		for(; p != pairs.end(); ++p)
		{
			os << p->first << '=' << p->second << std::endl;
		}
	}
}

void CIniFile::Save()
{
	std::ofstream out(pathname.c_str());
	Dump(out);
}

std::string CIniFile::get(std::string selection, std::string key)
{
	std::string val, group = selection;
	std::map<std::string, Pairs, std::greater<std::string> >::iterator pos = paragraph.find(group);
	if(pos != paragraph.end())
	{
		Pairs pairs = pos->second;
		Pairs::iterator p = pairs.find(key);
		if(p != pairs.end())
			val = p->second;
	}
	return val;
}

void CIniFile::set(std::string selection, std::string key, std::string value)
{
	modifyed = true;
	std::string group = selection;
	Pairs &pairs = paragraph[group];
	pairs[key] = value;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章