读写ini配置文件的模块

// -*- C++ header-*-

//=============================================================================
/**
*  @file    config.h
*
*  config.h,2005/04/19 slayer
*
*  @author slayer <slay78@hotmail.com>
*/

//=============================================================================

#ifndef _config_h_
#define _config_h_

#include "stdafx.h"
#include <hash_map>
#include <string>
#include <fstream>
#include <sstream>

using namespace std;
using namespace stdext;

class _key;

typedef class _Value
{
    
friend class _ini;
public:
    _Value(){};
    ~_Value(){};

    _Value(
const string& value):_value(value){};

    
inline _Value& operator=(const string& value){
        _value=value; 
return *this;};
    
inline _Value& operator=(const int& value){
        _caster.clear(); _caster << value; 
        _value = _caster.str(); 
return *this;};
    
inline _Value& operator=(const long& value){
        _caster.clear(); _caster << value; 
        _value = _caster.str(); 
return *this;};
    
inline _Value& operator=(const double& value){
        _caster.clear(); _caster << value; 
        _value = _caster.str(); 
return *this;};
    
inline _Value& operator=(const float& value){
        _caster.clear(); _caster << value; 
        _value = _caster.str(); 
return *this;};
    
inline _Value& operator=(const char *value){
        _caster.clear(); _caster << value; 
       
_value = _caster.str(); return *this;};

    
inline operator string() const    {return _value;};
    
inline operator int() const    {return atoi(_value.c_str());};
    
inline operator long() const    {return atol(_value.c_str());};
    
inline operator float() const    
       
{return static_cast<float>(atof(_value.c_str()));};
    
inline operator double() const    {return atof(_value.c_str());};


private:
    string _value;

    stringstream _caster;
//for convert
}Value;

inline ostream& operator<<(ostream& o, const Value& v){
    o << 
static_cast<string>(v); return o;};

typedef class _Key
{
    
typedef hash_map<string, Value> valueMap;
    
friend class _ini;
public:
    _Key(){};
    
inline void clear(){_values.clear();};
    
inline Value& operator[](const string& key){return _values[key];};
    
inline _Key& operator+=(const _Key& k)
    {
        valueMap::const_iterator i;
        
for (i = k._values.begin(); i != k._values.end(); i++)
            _values[i->first] = (string)i->second;
        
return *this;
    };

private:
    valueMap _values;
}Key;

typedef class _Section
{
    
typedef hash_map<string, Key> keyMap;
    
friend class _ini;
public:
    _Section(){};
    
inline Key& operator[](const string& section){return _keys[section];};
    
inline void clear(){_keys.clear();};
    
inline _Section& operator+=(const _Section& s)
    {
        keyMap::const_iterator i;
        
for (i = s._keys.begin(); i != s._keys.end(); i++)
            _keys[i->first] += i->second;
        
return *this;
    };


private:
    keyMap _keys;

}Section;

typedef class _ini
{
public:
    _ini(
const string& file):_file(file){};
    _ini(){_file.clear();};

    
inline int load(Section& secs){return load(secs,_file);};
    
int load(Section& secs,const string& file)
    {
        ifstream f(file.c_str(),ios::in);
        
if(!f.is_open())return -1;
        secs.clear();
        string section,key,value;
        string line;
        
while(!f.eof())
        {
            getline(f,line);
            
const char* s=line.c_str();
            
if(line.size()<3)continue;
            line=line.substr(line.find_first_not_of(
" /t"));
            
if(line.size()<3)continue;
            
if(is_comment(line))continue;
            
if(is_section(line,section))continue;
            
if(section.empty())continue;    // unknow line
            if(!parse_line(line,key,value))continue;
            cout<<section<<
","<<key<<","<<value<<","<<endl;
            secs[section][key]=value;
        }
        
return 0;
    }

    
int save(Section& secs,const string& file)
    {
        ofstream f(file.c_str(),ios::trunc);
        
const _Section::keyMap& keys=secs._keys;
        _Section::keyMap::const_iterator kit;

        
for(kit=keys.begin();kit!=keys.end();kit++)
        {
            f<<endl<<
"["<<kit->first<<"]"<<endl;

            
const _Key::valueMap& values=kit->second._values;
            _Key::valueMap::const_iterator vit;
            
for(vit=values.begin();vit!=values.end();vit++)
            {
                f<<vit->first<<
"="<<vit->second<<endl;
            }
        }


        
return 0;
    }

private:
    
bool parse_line(const string& line,string& key,string& value)
    {
        key.clear();value.clear();
        size_t n=line.find_first_of('=');
        
if(n == string::npos)return false;
        key = line.substr(0,n);
        value =line.substr(n+1);
        n = key.find_last_not_of(
" /t");
        key = key.substr(0,n+1);

        n = value.find_first_not_of(
" /t");
        
if(n == string::npos)return false;
        value=value.substr(n);
        n=value.find_last_not_of(
" /t");
        
if(n == string::npos)return false;
        value=value.substr(0,n+1);
        
if( ((n = value.find("/t#" ))  != string::npos)    ||
            ((n = value.find(
" #" ))   != string::npos)    ||
            ((n = value.find(
"/t//" )) != string::npos)    ||
            ((n = value.find(
" //" ))  != string::npos))
        {
            value = value.substr(0, n);
        }
        n=value.find_last_not_of(
" /t");
        
if(n == string::npos)return false;
        value=value.substr(0,n+1);
        
return true;
    }

    
inline bool is_comment(const string& line){
        
return line[0]=='#' || (line[0]=='/' && line[1]=='/');}

    
inline bool is_section(const string& line, string& sec)
    {
        
if(line[0]!='[' || line[1]==']')return false;
        size_t n=line.find_first_of(']');
        
if(n!=string::npos)
            sec=line.substr(1,n-1);
        
return true;
    }

private:
    string _file;
}Ini;


#endif //_config_h_

///test.cpp/
#include "config.h"

int _tmain(int argc, _TCHAR* argv[])
{
    Ini ini;
    Section s;
    string str=
"123";
    s[
"system"]["count"]=123;
    s[
"system"]["ip1"]="127.0.0.1";
    cout<<s[
"system"]["ip1"]<<endl;

    Section s1;

    s1[
"system"]["123"]="aaa";
    s1[
"abc"]["123"]="aaa";

    s+=s1;
//merge

    ini.save(s,"save.ini");


    str=s[
"system"]["ip1"];
    cout<<str<<endl;
 
    s[
"system"]["double"]=(double)12.311111111111111;
    str=s[
"system"]["int"];
    cout<<str<<endl;

    
float f= s["system"]["int"];
    cout << f <<endl;

    str=s[
"system"]["count"];
    str=s[
"system"]["ip1"];


    s.clear();
    str=s[
"system"]["count"];
    str=s[
"system"]["ip1"];


    ini.load(s,
"test.ini");



    
return 0;
}


test.ini/

#test
[sec1]
value1 = a string value  #xxxxxxxxxxxxxxxxxxxx
value 2 = 123 //
value_3 = abc

[system]
ip1 = 127.0.0.1
port1=8000

#thread count
threadcount = 50


[
[]
[1][]
123=3221


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值