Недавно появилось необходимость в классе для ini-файлов. Нашел какой-то на codeproject, но он отказывался работать при больших (всего-то 45 значений) конфигурациях. В итоге быстренько накатал свой собственный, с учетом своих нужд. Возможно кому-то он тоже пригодится. Методов немного, думаю всем будет понятно для чего они и без комментариев.
Зависимость от Runtime: да
Используемые экземпляры: wstring, wifstream, vector
Шаблон ini-файла (оставить последнюю строку пустой):
Код
# comment
; comment
[section]
key1=value1
key2=value2
\r\n
CIni.h:
Код
#pragma once
#include <string>
#include <vector>
#include <fstream>
using std::vector;
using std::wifstream;
using std::wstring;
class CIni
{
public:
/*
Описание параметра в файле
Название
Значение
*/
struct Parameter
{
wstring Name;
wstring Value;
};
/*
Описание секции в файле
Название секции
Количество параметров
Список параметров
*/
struct Section
{
wstring Name;
int param_num;
vector<Parameter> Content;
};
private:
// Зеркало файла в памяти
vector<Section> File;
public:
CIni (const wchar_t* filename);
bool GetSection(wstring name, Section& sect);
bool GetParameter(wstring sname, wstring pname, Parameter& param);
~CIni(void);
};
CIni.cpp
Код
#include "CIni.h"
CIni::CIni(const wchar_t* filename)
{
wifstream f;
wstring tmp;
Parameter param;
Section sect;
int sec_num = 0;
int par_num = 0;
int i = 0;
f.open(filename);
if (f)
{
while (!std::getline(f,tmp).eof())
{
if (tmp[0] == L'#' || tmp[0] == L';')
continue;
if (tmp[0] == L'[')
{
if (sec_num)
File.push_back(sect);
sect.Content.clear();
par_num = 0;
sec_num++;
i = tmp.find(L']');
sect.Name = tmp.substr(1,i-1);
}
else
{
i = tmp.find(L'=');
if (i)
{
param.Name = tmp.substr(0, i);
param.Value = tmp.substr(i+1, tmp.length());
sect.Content.push_back(param);
sect.param_num = ++par_num;
}
}
}
File.push_back(sect);
f.close();
}
}
bool CIni::GetParameter(wstring sname, wstring pname, Parameter& param)
{
int Ssz = File.size();
int Psz = 0;
for (int i = 0; i < Ssz; i++)
{
if (File[i].Name == sname)
{
Psz = File[i].Content.size();
for (int j = 0; j < Psz; j++)
{
if (File[i].Content[j].Name == pname)
{
param.Name = File[i].Content[j].Name;
param.Value = File[i].Content[j].Value;
return true;
}
}
}
}
return false;
}
bool CIni::GetSection(wstring name, Section& sect)
{
int Ssz = File.size();
int Psz = 0;
for (int i = 0; i < Ssz; i++)
{
if (File[i].Name == name)
{
sect.Content.clear();
sect.Name = File[i].Name;
sect.param_num = File[i].param_num;
Psz = File[i].Content.size();
sect.Content = File[i].Content;
}
}
return false;
}
CIni::~CIni(void)
{
File.clear();
}