这套代码适用于从服务器拉取INI,而不用保存到文件,而且是跨平台的.支持Unicode和Ansi.
而Windows 那套INI API先不说和平台绑死,他一定要访问文件的.
/* 王锐.2012.8.31 */ #pragma once #include <string> #include <vector> #include <map> template<typename T> class CMemIni { private: template<typename T> class CSection { public: private: friend CMemIni; std::map<T, T> mValues; }; std::map<T, CSection<T>> mSections; std::vector<T> split(const T& source, const int delimiter) { std::vector<T> result; T input = source; int lastIndex = 0; for (int index = 0; index < input.size(); index ++) { while(true) { if (input[lastIndex] == 0x0a) { lastIndex ++; } else break; } int c = input[index]; if(c == delimiter) { T substr = input.substr(lastIndex, index - lastIndex); lastIndex = index + 1; result.push_back(substr); } } T substr = input.substr(lastIndex, T::npos); result.push_back(substr); return result; } T trimleft(const T& str) { T::size_type pos = str.find_first_not_of(' '); if (pos == T::npos) { return str; } return str.substr(pos); } T trim(const T& str) { T::size_type pos = str.find_first_not_of(' '); if (pos == T::npos) { return str; } T::size_type pos2 = str.find_last_not_of(' '); if (pos2 != T::npos) { return str.substr(pos, pos2 - pos + 1); } return str.substr(pos); } T breakline(T & v) { v+='\r'; v+='\n'; return v; } public: CMemIni(T text) { setText(text); } CMemIni() { setText(text); } void setText(T text) { mSections.clear(); std::vector<T>? lines = split(text, 0x0d); int ln = 0; while(ln < lines.size()) { T line? = trim(lines[ln]); ln ++; if(line.size() > 0) { if(line[0] == '[' && line[line.size()-1] == ']') { CSection<T>? currentSection; T currentSectionName = line.substr(1, line.size() - 2); while(ln < lines.size()) { line = lines[ln]; if((line.size() > 0)) { if((line[0] == '[' && line[line.size()-1] == ']')) { break; } else { std::vector<T> keyvalue = split(line, '='); if(keyvalue.size()>0) { T _key = trim(keyvalue[0]); T _value; if(keyvalue.size()>1) _value = keyvalue[1]; currentSection.mValues[_key] = _value; } } } ln++; } mSections[currentSectionName] = currentSection; } } } } T getText() { T? ret; // for(std::map<T, CSection<T>>::iterator? i = mSections.begin(); i!= mSections.end(); ++i) { CSection<T> & currentSection = i->second; if(currentSection.mValues.size() > 0) { // T? line; line = '['; line += i->first; line += ']'; ret += breakline(line); // for(std::map<T, T>::iterator i = currentSection.mValues.begin(); i!= currentSection.mValues.end();i++) { T? _key = i->first; T? _value = i->second; line = _key; line += '='; line += _value; ret += breakline(line); } } } return ret; } void removeSection(T section) { std::map<T, CSection<T>>::iterator s = mSections.find(section); if(s != mSections.end()) mSections.erase(s); } void removeKey(T section, T key) { std::map<T, CSection<T>>::iterator s = mSections.find(section); if(s==mSections.end()) return; CSection<T>&? currentSection = s->second; std::map<T, T>::iterator? k = currentSection.mValues.find(key); if (k != currentSection.mValues.end()) currentSection.mValues.erase(k); } bool hasSection(T section) { CSection<T>? currentSection; std::map<T, CSection<T>>::iterator s = mSections.find(section); return (s!=mSections.end()); } bool hasKey(T section, T key) { std::map<T, CSection<T>>::iterator s = mSections.find(section); if(s==mSections.end()) return false; CSection<T>&? currentSection = s->second; std::map<T, T>::iterator? k = currentSection.mValues.find(key); return (k != currentSection.mValues.end()); } std::vector<T> getSections() { std::vector<T>? ret; for(std::map<T, CSection<T>>::iterator s = mSections.begin(); s != mSections.end(); s++) { ret.push_back(s->first); } return ret; } std::vector<T> getKeys(T section) { std::vector<T>? ret; std::map<T, CSection<T>>::iterator s = mSections.find(section); if(s != mSections.end()) { CSection<T>&? currentSection = s->second; for(std::map<T, T>::iterator? k = currentSection.mValues.begin(); k != currentSection.mValues.end(); k ++) { ret.push_back(k->first); } } return ret; } T readStr(T section, T key, T defValue) { std::map<T, CSection<T>>::iterator s = mSections.find(section); if(s==mSections.end()) return defValue; CSection<T>&? currentSection = s->second; std::map<T, T>::iterator? k = currentSection.mValues.find(key); if(k == currentSection.mValues.end()) return defValue; return currentSection.mValues[key]; } void writeStr(T section, T key, T _Value) { CSection<T>? currentSection; std::map<T, CSection<T>>::iterator s = mSections.find(section); if(s!=mSections.end()) currentSection = s->second; currentSection.mValues[key] = _Value; mSections[section] = currentSection; } }; typedef CMemIni<std::wstring> CWideMemIni; typedef CMemIni<std::string>? CAnsiMemIni; #ifdef UNICODE #define?? CTMemIni CWideMemIni #else #define?? CTMemIni CAnsiMemIni #endif