自造轮子-ini文件处理

该文章描述了一个C++实现的类`tConfigFile`,用于处理类似ini格式的配置文件,包括读取、写入以及处理含有注释的文件。类中包含了解析文件、保存到文件、设置和获取键值对以及显示文件内容的方法。示例代码展示了如何创建和使用这个类进行配置操作。

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

处理类似ini文件,但是包含注释的文件
config.ini

[config1]
key1=value1
key1=value2
key3=value3

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

tConfigFile.h

#ifndef __T_CONFIG_FILE_H
#define __T_CONFIG_FILE_H

#include <iostream>
#include <string>
#include <list>
#include <map>
#include <vector>
#include <sstream>
#include <fstream>
#include <string.h>
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);
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 configShow(map<string,map<string,ValueInfo> >::iterator itr_config);
	void keyShow(map<string,ValueInfo>::iterator &itr_key);	

};
void testConfigDemo();



#endif


#include "tConfigFile.h"

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

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;
}

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;
}

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;
}
/*
&value :对应config中key的值的拷贝
*/
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;
}



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;

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值