写了一个简单的处理类似xml文件的类,请大家指正【原创】

说明:只是个菜鸟,贴出来的目的是希望有大侠指点一下,不足之处,c++学习时间不长,呵。或者帮忙测试一下,共同完善之。

头文件:

//=========================================================
//
// Copyright (c) 2000-2005 TT Technologies,Co. Ltd.
// All Rights Reserved.
//
// Class: CTTXmlFile
//
// Product: TTLibrary
// File   : TTXmlFile.h
// Author : http://blog.csdn.net/waterpub
// Created: 2005.03.07 11:30
//  
// Description:
//     ValueAdded main program for TTLibrary.
//                   Contact:ShenZhen @ GuangDong
//                       waterpub@mail.csdn.net
//
//========================================================= 
#pragma once 
#include "string" 
#include "vector" 
#include "utility" 
#include "algorithm" 
using namespace std;

namespace TTLibrary
{
	// 维护一个xml条目的类
	class CTTXmlItem
	{
	public:
		CTTXmlItem(const string& sItemName);
		~CTTXmlItem();
		inline bool SetKeyValue(const string& sKey, const string& sValue);
		inline bool SetKeyValue(const string& sKey, const int& nValue);
		inline bool GetKeyValueString(const string& sKey, string& sValue) const;
		inline bool GetKeyValueInt(const string& sKey, int& nValue) const;
		inline bool MergeAnother(const CTTXmlItem& xi);
		inline string GetItemName() const{ return m_sItemName; }
#ifdef _DEBUG 
		void Debug();
#endif 

	private:
		const vector<pair<string, string> >* GetKeyVector() const;

	private:
		string m_sItemName;							// 条目名
		vector<pair<string, string> > m_KeyVector;	// 该条目下的键值列表
		friend class CTTXmlFile;

	private:
		class CTTXmlItemFind						// 查找键值的仿函数
		{
		public:
			CTTXmlItemFind(const string& sKey)
			{
				m_sKey = sKey;
			}
			bool operator() (const pair<string, string>& XmlItemData)
			{
				if (XmlItemData.first == m_sKey) 
				{
					return true;
				}
				else
				{
					return false;
				}
			}
		private:
			string	m_sKey;
		};
	};

	// 加载xml并解析的类
	class CTTXmlFile
	{
	public:
		CTTXmlFile(void);
		~CTTXmlFile(void);

	public:
		bool clear();
		bool Load(const string& sFileName);
		bool Save(const string& sFileName = "");
		bool AddItem(const CTTXmlItem& xi);
		bool RemoveItem(const string& sItemName);
#ifdef _DEBUG 
		void Debug();
#endif 

	private:
		bool ParseItem(char* &pStr);
		bool ParseKey(char* &pStr, CTTXmlItem& xi);
		bool SkipBlank(char* &pStr);
		bool SkipEqualChar(char* &pStr);
		bool FindWord(char* &pStr, string& sWord);

	private:
		string				m_sFileName;	// 加载的文件名
		vector<CTTXmlItem>	m_ItemVector;	// 条目列表

	private:
		class CTTXmlItemFind				// 查找xml条目列表中有否相同名字的条目的仿函数
		{
		public:
			CTTXmlItemFind(const string& sItemName)
			{
				m_sItemName = sItemName;
			}
			bool operator() (const CTTXmlItem& xi)
			{
				if (xi.GetItemName() == m_sItemName) 
				{
					return true;
				}
				else
				{
					return false;
				}
			}

		private:
			string	m_sItemName;
		};
	};
}





实现文件:

  
   
  
  
#include "StdAfx.h" 
#include "ttxmlfile.h" 

namespace TTLibrary
{
	CTTXmlItem::CTTXmlItem(const string& sItemName)
	{
		m_sItemName = sItemName;
	}

	CTTXmlItem::~CTTXmlItem()
	{
	}

	bool CTTXmlItem::SetKeyValue(const string& sKey, const string& sValue)
	{
		vector<pair<string, string> >::iterator it = find_if(m_KeyVector.begin(), m_KeyVector.end(), 
			CTTXmlItemFind(sKey));
		if (it != m_KeyVector.end()) 
		{
			(*it).second = sValue;
		}
		else
		{
			pair<string, string> XmlItemData;
			XmlItemData.first = sKey;
			XmlItemData.second = sValue;
			m_KeyVector.push_back(XmlItemData);
		}

		return true;
	}

	bool CTTXmlItem::SetKeyValue(const string& sKey, const int& nValue)
	{
		string sValue;
		char szValue[26];
		itoa(nValue, szValue, 10);
		sValue = szValue;
		SetKeyValue(sKey, sValue);
		return true;
	}

	bool CTTXmlItem::GetKeyValueString(const string& sKey, string& sValue) const
	{
		vector<pair<string, string> >::const_iterator it = find_if(m_KeyVector.begin(), m_KeyVector.end(), 
			CTTXmlItemFind(sKey));
		if (it != m_KeyVector.end()) 
		{
			sValue = (*it).second;
			return true;
		}
		else
		{
			return false;
		}
	}

	bool CTTXmlItem::GetKeyValueInt(const string& sKey, int& nValue) const
	{
		vector<pair<string, string> >::const_iterator it = find_if(m_KeyVector.begin(), m_KeyVector.end(), 
			CTTXmlItemFind(sKey));
		if (it != m_KeyVector.end()) 
		{
			nValue = atoi((*it).second.c_str());
			return true;
		}
		else
		{
			return false;
		}
	}

	const vector<pair<string, string> >* CTTXmlItem::GetKeyVector() const
	{
		return &m_KeyVector;
	}

	bool CTTXmlItem::MergeAnother(const CTTXmlItem& xi)
	{
		if (xi.GetItemName() == m_sItemName)
		{
			vector<pair<string, string> >::const_iterator it = (xi.GetKeyVector())->begin();
			for(; it != (xi.GetKeyVector())->end(); it++)
			{
				SetKeyValue((*it).first, (*it).second);
			}
		}

		return true;
	}

#ifdef _DEBUG 
	void CTTXmlItem::Debug()
	{
		XTRACE("     ===========================/n");
		XTRACE(RGB(0, 0, 255), "     条目名:%s/n", m_sItemName.c_str());
		vector<pair<string, string> >::iterator it = m_KeyVector.begin();
		for(; it != m_KeyVector.end(); it++)
		{
			XTRACE("     键:%s,值:%s/n", (*it).first.c_str(), (*it).second.c_str());
		}
	}
#endif 

	CTTXmlFile::CTTXmlFile(void)
	{
	}

	CTTXmlFile::~CTTXmlFile(void)
	{
	}

	bool CTTXmlFile::AddItem(const CTTXmlItem& xi)
	{
		vector<CTTXmlItem>::iterator it = find_if(m_ItemVector.begin(), m_ItemVector.end(), 
			CTTXmlItemFind(xi.GetItemName()) );
		if (it != m_ItemVector.end()) 
		{
			(*it).MergeAnother(xi);
			return false;
		}
		else
		{
			// 没有此条目则添加
			m_ItemVector.push_back(xi);
			return true;
		}
	}

	bool CTTXmlFile::RemoveItem(const string& sItemName)
	{
		vector<CTTXmlItem>::iterator it = find_if(m_ItemVector.begin(), m_ItemVector.end(), 
			CTTXmlItemFind(sItemName) );
		if (it != m_ItemVector.end()) 
		{
			// 有此条目则删除
			m_ItemVector.erase(it);
			return true;
		}
		else
		{
			return false;
		}
	}

	bool CTTXmlFile::clear()
	{
		m_ItemVector.clear();
		m_sFileName.clear();

		return true;
	}

	bool CTTXmlFile::Load(const string& sFileName)
	{
		if (sFileName.empty()) return false;
		char szDirBuf[MAX_PATH] = "";
		GetCurrentDirectory(MAX_PATH, szDirBuf);
		strncat(szDirBuf, "//", strlen("//"));
		strncat(szDirBuf, sFileName.c_str(), sFileName.size());

		clear();
		m_sFileName = szDirBuf;
		FILE* hFile = fopen(m_sFileName.c_str(), "r");
		if (NULL == hFile) return false;

		string strText;
		char* szBuf = new char[1024 + 1];

		while (!feof(hFile))
		{
			int nRead = (int)fread(szBuf, 1, 1024, hFile);
			if (nRead > 0) 
			{
				szBuf[nRead] = NULL;
				strText += szBuf;
			}
		}
		fclose(hFile);

		char* pStr = (char*)strText.c_str();
		// 解析文件
		while (pStr != NULL) 
		{
			if(!ParseItem(pStr)) break;
		}

#ifdef _DEBUG 
		Debug();
#endif 

		delete []szBuf;
		return true;
	}

	bool CTTXmlFile::Save(const string& sFileName)
	{
		return true;
	}

	// 从文件中解析出一个条目
	bool CTTXmlFile::ParseItem(char* &pStr)
	{
		char* pStart = pStr;
		while (*pStart != '<' && *pStart != NULL) 
			pStart++;

		if (*pStart == NULL)
		{
			pStr = pStart;
			return false;	// 解析文件结束
		}
		else
		{
			pStart++;		// 从'<'后面开始
			SkipBlank(pStart);

			// 解析条目名
			string sItemName;
			if(FindWord(pStart, sItemName))
			{
				CTTXmlItem xi(sItemName);

				// 解析键值
				ParseKey(pStart, xi);
#ifdef _DEBUG 
				//			xi.Debug();
#endif 
				m_ItemVector.push_back(xi);
			}
			// 消除对应的'>'字符
			SkipBlank(pStart);
			if (*pStart == '>') pStart++; 
			pStr = pStart;

			return true;
		}

	}

	bool CTTXmlFile::ParseKey(char* &pStr, CTTXmlItem& xi)
	{
		string sKey;
		string sValue;
		while (FindWord(pStr, sKey)) 
		{
			if( SkipEqualChar(pStr))
			{
				if( FindWord(pStr, sValue))
				{
					xi.SetKeyValue(sKey, sValue);
				}
			}
		}
		SkipBlank(pStr);

		return true;
	}

	bool CTTXmlFile::SkipBlank(char* &pStr)
	{
		while ((*pStr > 0 && *pStr < 33))
			pStr++;

		return true;
	}

	bool CTTXmlFile::SkipEqualChar(char* &pStr)
	{
		SkipBlank(pStr);
		if (*pStr == '=')
		{
			pStr++;
			return true;
		}
		else
			return false;
	}

	// 字符串,不能为 '<' 或 '>' 或 '='
	bool CTTXmlFile::FindWord(char* &pStr, string& sWord)
	{
		SkipBlank(pStr);
		char* pStart = pStr;
		while ((*pStart >= 33 || *pStart < 0) && *pStart != '<' && *pStart != '>' && *pStart != '=')
			pStart++;

		if (pStart == pStr)
		{
			pStr = pStart;
			return false;
		}
		else
		{
			string strTemp(pStr, pStart);
			sWord = strTemp;

			pStr = pStart;
			return true;
		}

	}

#ifdef _DEBUG 
	void CTTXmlFile::Debug()
	{
		XTRACE("***********************************************/n");
		XTRACE(RGB(255, 0, 0), "文件名:%s/n", m_sFileName.c_str());
		XTRACE("***********************************************/n");
		vector<CTTXmlItem>::iterator it = m_ItemVector.begin();
		for(; it!= m_ItemVector.end(); it++)
		{
			(*it).Debug();
		}
	}
#endif 
}



   
   
测试文件:test.ini,如下(写的很乱,作为加强测试,):

   
   
fdsafd
fdsafds
< ><aaaaa=sfd
< >>
< aa>fdsafds
< tt aaa = bbb  >
< test >
<name Name1=ccc name2 = ddd> 测试代码:  CTTXmlFile ttxf;
 ttxf.Load("skin2.ini");
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值