说明:只是个菜鸟,贴出来的目的是希望有大侠指点一下,不足之处,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 // [email protected] // //========================================================= #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");
本文地址:http://com.8s8s.com/it/it22989.htm