今天有需要寫一個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;
}