ini文件处理

该代码实现了一个C++类`tConfigFile`,用于读取、解析和保存配置文件。类支持#开头的注释,可以处理包含多个配置块的文件,并提供了设置和获取配置值的方法。需要注意的是,由于类未对多线程操作进行加锁,因此在多线程环境中可能产生意外结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
构造函数完成了文件的解析,并把内容保存在map中
析构时会重新把map写回文件
API只实时针对map修改
意味着:多线程进程操作不加锁可能会有意外的结果

支持#开头的注释
*/
#include "tConfigFile.h"

//#define LOG(a) cout << (a) <<endl
#define LOG(a) 


/*
str_is_file: ture,str是文件名;false,str否则是字符串
*/
tConfigFile::tConfigFile(string str,bool str_is_file)
{
    
    file_change = false;
    coinfig_is_file = str_is_file;
    if(str_is_file)
    {
        fileName =  str;
        ParseFile();
    }
    else
    {        
        strBuf = str;             
        ParseString();
    }
}

tConfigFile::~tConfigFile()
{
    if(file_change&&coinfig_is_file)
    {
        file_change = false;
        SaveToFile();
    }
}

string &tConfigFile::trim(string &str,const string &chars=" \t")
{
        string map(0xFF, 0); 
        for (unsigned int i=0;i<chars.size();i++) 
        { 
                map[chars[i]] = 1; 
        } 
        while( str.size() && map.at(str[str.size()-1])) str.erase(str.end()-1); 
        while( str.size() && map.at(str[0])) str.erase(0,1); 
        return str;
}

bool tConfigFile::Parse(basic_istream<char> &ss)
{
        configs.clear();
        map<string,ValueInfo> config;
        string name;
        ValueInfo vi;

        string line;
        while(getline(ss,line))
        {
                LOG("#line=#" + line + "#");
                if(line.empty())
                        continue;
                
                if(line[0]=='[')
                {
                    unsigned int  a =  line.find(']');
                        
                    if(a != string::npos)
                    {
                        if(!name.empty())
                       {
                               configs[name] = config;
                       }
                       
                       name.clear();
                       config.clear();

                       string tmp = line.substr(1,a-1);
                       trim(tmp);
                       if(!tmp.empty())
                          {
                           name = tmp;
                          
                           LOG("-----------");
                           LOG("name=[" + name + "]");
                       }
                       else
                       {
                             //[] 为空的行丢弃
                       }

                    }    
                    else
                    {
                        // 单[开头的行直接丢弃
                        
                    }
                }
                else
                {       
                        if(!name.empty())
                        {    
                              
                                if(line[0]=='#')
                                {   
                                      vi.info.push_back(line.substr(1)); 
                                      LOG("info=[" + line.substr(1) + "]");                           
                                }
                                else                        
                                {
                                        unsigned int a = line.find('=');
                                        if(a != string::npos)
                                        {
                                               
                                                string key = line.substr(0,a);
                                                string value = line.substr(a+1);
                                                trim(key);
                                                trim(value);
                                                if(!key.empty())
                                                {
                                                        vi.value = value;
                                                        config[key] = vi;
                                                        LOG("name=[" + key + "]");
                                                        LOG("value=[" + value + "]");

                                                        vi.info.clear();
                                                        vi.value.clear();
                                                }  
                                        }
                                         
                                }   
                        }
                }
        } 

        if(!name.empty())
        {
                configs[name] = config;        
        }
        LOG("-----------");
        return true;
}

bool tConfigFile::ParseString()
{
        istringstream ss(strBuf);
        return Parse(ss);
}

bool tConfigFile::ParseFile()
{
        LOG("Parse:");
        ifstream ifs;
        ifs.open(fileName.c_str()) ;
        if (!ifs.is_open()) {
                LOG("open " + fileName + " err");
                return false;
        }
        return Parse(ifs);
}

bool tConfigFile::SaveToFile()
{

        LOG("SaveToFile");
        ofstream ofs;
        ofs.open(fileName.c_str());
        if (!ofs.is_open()) {
            LOG("open " + fileName + " err");
                    return false;
        } 

        map<string,map<string,ValueInfo> >::iterator itr;
        for(itr=configs.begin();itr!=configs.end();itr++)
        {
                ofs << endl << "[" << itr->first << "]" << endl; 
                LOG("[" + itr->first + "]"); 
                map<string,ValueInfo>::iterator itr1;
                for(itr1=itr->second.begin();itr1!=itr->second.end();itr1++)
                {
                        if(!itr1->second.info.empty())
                        {
                                for(unsigned int i=0;i<itr1->second.info.size();i++)
                                {
                                        ofs << "#" << itr1->second.info[i] << endl; 
                                        LOG(itr1->second.info[i]);
                                }                      
                        }
                        ofs << itr1->first << "=" << itr1->second.value << endl;  
                        LOG(itr1->first + "=" + itr1->second.value);           
                }

        }
        ofs.close();
        return true;
}


/*
没有则创建,有则替换
[config_name]
#info[0]
#info[.]
#info[n]
key=value
*/
bool tConfigFile::set(string config_name,string key,string value,vector<string> &info)
{
        if(config_name.empty() || key.empty())
        {
                return false;
        }

        map<string,map<string,ValueInfo> >::iterator itr =  configs.find(config_name);
        if(itr==configs.end())
        {
                ValueInfo vi; 
                vi.info = info;
                vi.value = value;  
                map<string,ValueInfo> block;
                block[key] = vi;
                configs[config_name]  = block;
        }
        else
        {    
                ValueInfo vi;
                vi.info = info;
                vi.value = value;

                map<string,ValueInfo>::iterator itr1=itr->second.find(key);
                if(itr1==itr->second.end())
                {
                        itr->second[key] = vi; 
                }
                else
                {
                        itr1->second = vi;    
                }
        }  
        file_change = true;
        return true;
}

/*
没有则创建,有则替换
[config_name]
key=value
*/
bool tConfigFile::set(string config_name,string key,string value)
{
        if(config_name.empty() || key.empty())
        {
                return false;
        }

        map<string,map<string,ValueInfo> >::iterator itr =  configs.find(config_name);
        if(itr==configs.end())
        {
                ValueInfo vi; 
                vi.value = value;  
                map<string,ValueInfo> block;
                block[key] = vi;
                configs[config_name]  = block;
        }
        else
        {    
                ValueInfo vi;
                vi.value = value;

                map<string,ValueInfo>::iterator itr1=itr->second.find(key);
                if(itr1==itr->second.end())
                {
                        itr->second[key] = vi; 
                }
                else
                {
                        itr1->second.value = value;     
                }
        }  
        file_change = true;
        return true;
}

/*
&itr_config : 对应config 的迭代器
*/
bool tConfigFile::findConfig(string config_name,map<string,map<string,ValueInfo> >::iterator &itr_config)
{
        map<string,ValueInfo> empty;
        if(config_name.empty())
        {
                return false;
        }

        itr_config = configs.find(config_name);
        if(itr_config==configs.end())
        {
                return false;
        }
        return true;
}

/*
&itr_key:对应config中对应key-value 迭代器
*/
bool tConfigFile::findConfigKey(string block_name,string key,map<string,ValueInfo>::iterator &itr_key)
{
       ValueInfo empty;
        
        map<string,map<string,ValueInfo> >::iterator itr = configs.find(block_name);
        if(itr==configs.end())
        {
                return false;
        }
        itr_key=itr->second.find(key);
        if(itr_key==itr->second.end())
        {
                return false;
        }
        return true;;
}
/*
&config: 对应config 中所有key-value
*/
bool tConfigFile::getConfig(string config_name,map<string,ValueInfo> &config)
{
        map<string,ValueInfo> empty;
        if(config_name.empty())
        {
                return false;
        }

        map<string,map<string,ValueInfo> >::iterator itr_config = configs.find(config_name);
        if(itr_config==configs.end())
        {
                return false;
        }
        config = itr_config->second;
        return true;
}
/*
查找map中的如下结构,返回value
[config_name]
key=value
*/
bool tConfigFile::get(string config_name,string key,string &value)
{
       ValueInfo empty;
        
        map<string,map<string,ValueInfo> >::iterator itr = configs.find(config_name);
        if(itr==configs.end())
        {
                return false;
        }
        map<string,ValueInfo>::iterator itr_key=itr->second.find(key);
        if(itr_key==itr->second.end())
        {
                return false;
        }
        value = itr_key->second.value;
        return true;
}


/*
查找map中的如下结构,返回info
[config_name]
#
key=value
*/
bool tConfigFile::get(string config_name,string key,string value,vector<string> &info)
{
    ValueInfo empty;

    map<string,map<string,ValueInfo> >::iterator itr = configs.find(config_name);
    if(itr==configs.end())
    {
            return false;
    }
    map<string,ValueInfo>::iterator itr_key=itr->second.find(key);
    if(itr_key==itr->second.end())
    {
            return false;
    }
    value = itr_key->second.value;
    info = itr_key->second.info;
    return true;;    
}


void tConfigFile::fileShow()
{
        map<string,map<string,ValueInfo> >::iterator itr=configs.begin();
        for(;itr!=configs.end();itr++)
        {
            configShow(itr);
        }
}

void tConfigFile::configShow(map<string,map<string,ValueInfo> >::iterator itr_config)
{
        cout << "["<<itr_config->first << "]"<< endl;
        map<string,ValueInfo>::iterator itr_key;
        for(itr_key=itr_config->second.begin();itr_key!=itr_config->second.end();itr_key++)
        {
            keyShow(itr_key);
        }
}

void tConfigFile::keyShow(map<string,ValueInfo>::iterator &itr_key)
{
    
        for(unsigned int i=0;i<itr_key->second.info.size();i++)
        {
            cout << "#" <<itr_key->second.info[i] << endl;
        }
        cout <<itr_key->first << " = " <<itr_key->second.value << endl;    
}



void testConfigDemo()
{
    tConfigFile cc("new-config.txt");
    cc.set("config1","key1","abc");

    string value1;
    cc.get("config1","key1",value1);
    cout << "value1=" << value1 << endl;
}


#ifndef __T_CONFIG_FILE_H
#define __T_CONFIG_FILE_H

#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <sstream>
#include <fstream>
using namespace std;
/*
[config1]
key1=value1
key1=value2
key3=value3

[config2]
key1=value1
key2=value2
#注释
#注释
key3=value3
[config2]
#注释
key5=value5
key6=value6
bbb=ccc

*/
typedef struct
{
    vector<string> info;
    string value;
}ValueInfo;

class tConfigFile
{
private:
    /* data */
    bool file_change;
    bool coinfig_is_file;
    string fileName;
    string strBuf;
    map<string,map<string,ValueInfo> > configs;//<name,<key,value>>
    bool Parse(basic_istream<char> &ss);
    bool ParseFile();
    bool ParseString();
    bool findConfig(string config_name,map<string,map<string,ValueInfo> >::iterator &itr_config);
    bool findConfigKey(string config_name,string key,map<string,ValueInfo>::iterator &itr_key);
    bool getConfig(string config_name,map<string,ValueInfo> &config);
    
    bool SaveToFile();
    string &trim(string &str,const string &chars);
    void configShow(map<string,map<string,ValueInfo> >::iterator itr_config);
    void keyShow(map<string,ValueInfo>::iterator &itr_key);    
public:
    tConfigFile(string str,bool str_is_file=true);
    ~tConfigFile();

    bool set(string config_name,string key,string value,vector<string> &info);
    bool get(string config_name,string key,string value,vector<string> &info);
    
    bool set(string config_name,string key,string value);
    bool get(string config_name,string key,string &value);
    
    void fileShow();    

};
void testConfigDemo();



#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值