文件读取ini文件另一种读取办法
時間緊張,先記一筆,后續優化與完善。
????Windows下的ini文件的讀取可以應用系統提供的api來實現
????
????GetPrivateProfileString
????GetPrivateProfileInt
????...
????現實應用中, 如果不應用一種同一的方法來包裝一下會讓源代碼看起來很亂。
????所以,須要計劃一個便利,雅觀,直觀的配置文件操作類!
????
????準則是代碼難看,輕易維護
????
????需求:
????直觀的調用形式
????實現潛規則
????滿足各類數據(實現api經常應用的數據類型)
????
????
解釋:????
- 直觀的調用形式是什么意思
以減少鍵盤輸入和見文知意為準則的計劃方式,把長函數名變為符號。用符號來表示操作
- 潛規則
在配置ini訪問中的潛規則是
1.?Wiki上對ini的定義
? ? INI文件有節的觀點節用 [] 包圍,類似數據中的表名稱,如
[startup]
? ? 名稱/值對,類似數據庫表中的字段,如
TargetIP=10.0.0.1
? ? 注釋, 以";"為注釋的開始,到行尾,如
MenuOne=File... ; 菜單的第一項文字描述
2. Windows系統中操作ini文件時有#掃尾的行是疏忽的,如: #對打印機的設置
- 滿足各類數據,在ini中經常應用的數據有兩種,字符串和整型數據,滿足所有數據類型明顯不現實,可以在之后根據不同須要進行擴展
CIniAccessor accessor(_T("config.ini")); accessor[_T("startup")][_T("TargetIP")] = _T("10.0.0.100");
3. 更新
CIniAccessor accessor(_T("config.ini")); accessor.Update(); // 從磁盤上更新 accessor.Commit(); // 寫入磁盤
????
上面是數據結構 每日一道理無知者為夢想中的虛幻而苦苦等待,換回的不是所求的,而是歲月在臉上留下的印痕,一事無成的人一生便是虛度。生活中,與其花時間去等待,不如加快步伐去追尋理想,試著與時間賽跑,也許身軀、心理會感到勞累,但這樣的生活畢竟是充實的。
typedef struct tagAccessorData {union VALUETYPE{LONG longValue;TCHAR * pszValue;}value;enum{TYPE_EMPTY, TYPE_LONG, TYPE_CHAR}valuetype;tagAccessorData():valuetype(TYPE_EMPTY){} }ACCESSORDATA;
class CCoAccessorImpl:public ACCESSORDATA { private: TCHAR m_szTemp[30]; public:CCoAccessorImpl(){valuetype = TYPE_EMPTY;value.longValue = 0;}CCoAccessorImpl(const CCoAccessorImpl & acc){valuetype = acc.valuetype;if(acc.valuetype == TYPE_CHAR){value.pszValue = new TCHAR[_tcslen(acc.value.pszValue) + 1];ZeroMemory(value.pszValue, sizeof(TCHAR) * (_tcslen(acc.value.pszValue) + 1));_tcscpy(value.pszValue, acc.value.pszValue);}else{value.longValue = acc.value.longValue;}}CCoAccessorImpl(const LONG lValue){valuetype = TYPE_LONG;value.longValue = lValue;}CCoAccessorImpl(LPCTSTR lpszValue){valuetype = TYPE_CHAR;value.pszValue = new TCHAR[_tcslen(lpszValue) + 1];ZeroMemory(value.pszValue, sizeof(TCHAR) * (_tcslen(lpszValue) + 1));_tcscpy(value.pszValue, lpszValue);}~CCoAccessorImpl(){if(valuetype == TYPE_CHAR) delete [] value.pszValue;}CCoAccessorImpl & operator = (const CCoAccessorImpl& acc){if(valuetype == TYPE_CHAR) delete [] value.pszValue;value.longValue = 0;valuetype = acc.valuetype;if(acc.valuetype == TYPE_CHAR){value.pszValue = new TCHAR[_tcslen(acc.value.pszValue) + 1];ZeroMemory(value.pszValue, sizeof(TCHAR) * (_tcslen(acc.value.pszValue) + 1));_tcscpy(value.pszValue, acc.value.pszValue);}else{value.longValue = acc.value.longValue;}return *this;}CCoAccessorImpl & operator = (const LONG lValue){if(valuetype == TYPE_CHAR) delete [] value.pszValue;valuetype = TYPE_LONG;value.longValue = lValue;return *this;}CCoAccessorImpl & operator = (LPCTSTR lpszValue){if(valuetype == TYPE_CHAR) delete [] value.pszValue;valuetype = TYPE_CHAR;value.pszValue = new TCHAR[_tcslen(lpszValue) + 1];ZeroMemory(value.pszValue, sizeof(TCHAR) * (_tcslen(lpszValue) + 1));_tcscpy(value.pszValue, lpszValue);return *this;}operator LPCTSTR (){ switch(valuetype){ case TYPE_LONG: return _ltot(value.longValue, m_szTemp, 10);case TYPE_CHAR: return value.pszValue;}return _T("");}operator LONG (){ switch(valuetype){case TYPE_LONG:case TYPE_EMPTY:return value.longValue;}return _ttol(value.pszValue);}CCoAccessorImpl operator ()(LPCTSTR lpsz) //default value{if(valuetype == TYPE_EMPTY) return CCoAccessorImpl(lpsz);return *this;}CCoAccessorImpl operator ()(LONG lValue) //default value{if(valuetype == TYPE_EMPTY) return CCoAccessorImpl(lValue);return *this;}}; typedef std::basic_string<TCHAR> TCharArray;struct less {bool operator()(const TCharArray& _Left, const TCharArray& _Right) const{ return _tcsicmp(_Left.c_str(), _Right.c_str()) < 0;} };template<class ValueType, BOOL bSensitive> class CKeyValueArray:public std::map<TCharArray, ValueType, less> { public:CKeyValueArray(){}~CKeyValueArray(){}ValueType & operator[](TCharArray charArray){if(!bSensitive) _tcsupr((TCHAR*)charArray.data());return std::map<TCharArray, ValueType, less>::operator[](charArray);} }; // 讀文件操作 template<class Storage> struct iniparser {BOOL operator()(Storage & store, LPCTSTR lpszFilePath){HANDLE hFile = CreateFile(lpszFilePath, // file to openGENERIC_READ, // open for readingFILE_SHARE_READ, // share for readingNULL, // default securityOPEN_EXISTING, // existing file onlyFILE_ATTRIBUTE_NORMAL, // normal fileNULL); // no attr. templateif (hFile == INVALID_HANDLE_VALUE) { return FALSE; }TCHAR sz[2] = {0};DWORD dwRead = 0;TCharArray tcaLine;TCharArray tcaSectionName;struct foo{static void parse(Storage & store, TCharArray & tcaSectionName, TCharArray & tcaLine){if(!tcaLine.size()) return;// parse []TCHAR szComment[MAX_PATH] = {0};if(tcaLine.at(0) == _T('#')) return;TCharArray sSec;if(_stscanf(tcaLine.c_str(), _T("[%[^]]]"), (TCHAR*)sSec.assign(MAX_PATH,0).data())){tcaSectionName = sSec;}else{// parse key = valueTCHAR szKey[MAX_PATH] = {0};TCHAR szValue[MAX_PATH] = {0};if(2 == _stscanf(tcaLine.c_str(), _T("%[^=]=%[^\0]"), szKey, szValue)) {store[tcaSectionName][szKey] = szValue;}}}};while(ReadFile(hFile, sz, sizeof(TCHAR),&dwRead, NULL)){if(!dwRead) break;if(!(sz[0] == _T('\r') || sz[0] == _T('\n'))) {tcaLine.push_back(sz[0]);continue;}foo::parse(store, tcaSectionName, tcaLine);tcaLine.clear();tcaLine.reserve(); }CloseHandle(hFile);foo::parse(store, tcaSectionName, tcaLine); return TRUE;} }; // 寫文件操作 template<class Storage> struct inipersistor {BOOL operator()(Storage & store, LPCTSTR lpszFilePath){HANDLE hFile = CreateFile(lpszFilePath, // file to openGENERIC_WRITE, // open for readingFILE_SHARE_WRITE, // share for readingNULL, // default securityOPEN_ALWAYS, // existing file onlyFILE_ATTRIBUTE_NORMAL, // normal fileNULL); // no attr. templateif (hFile == INVALID_HANDLE_VALUE) { return FALSE; }for(Storage::iterator it = store.begin();it != store.end();it++){TCharArray tcaSectionName = (*it).first;Storage::mapped_type & kva = (*it).second;DWORD dwWritten = 0;WriteFile(hFile, _T("["), sizeof(TCHAR), &dwWritten, NULL); WriteFile(hFile, tcaSectionName.c_str(), sizeof(TCHAR) * tcaSectionName.size(), &dwWritten, NULL);WriteFile(hFile, _T("]\r\n"), sizeof(TCHAR) * 3, &dwWritten, NULL);for(Storage::mapped_type::iterator itKeyVal = kva.begin();itKeyVal != kva.end();itKeyVal++){TCharArray tcaKey = (*itKeyVal).first;TCharArray tcaVal = (*itKeyVal).second;WriteFile(hFile, tcaKey.c_str(), sizeof(TCHAR) * tcaKey.size(), &dwWritten, NULL);WriteFile(hFile, _T("="), sizeof(TCHAR), &dwWritten, NULL); WriteFile(hFile, tcaVal.c_str(), sizeof(TCHAR) * tcaVal.size(), &dwWritten, NULL);WriteFile(hFile, _T("\r\n"), sizeof(TCHAR) * 2, &dwWritten, NULL);}}CloseHandle(hFile);return TRUE;} };
template<class ValueType = CCoAccessorImpl, BOOL bSensitive = FALSE,class Parser = iniparser<std::map<TCharArray, CKeyValueArray<ValueType,bSensitive>,less > >,class Persistor = inipersistor<std::map<TCharArray, CKeyValueArray<ValueType,bSensitive>,less > > > class TIniAccessor { public:private:Parser _parser;Persistor _persistor;TCharArray m_szFileName; public:TIniAccessor(LPCTSTR lpsz):_parser(Parser()),_persistor(Persistor()){m_szFileName = lpsz;_parser(m_sectionarray, m_szFileName.c_str());}BOOL Update(){return _parser(m_sectionarray, m_szFileName.c_str());}BOOL Commit(LPCTSTR lpszSaveIniFile = NULL){TCharArray tca = m_szFileName;if(lpszSaveIniFile) tca = lpszSaveIniFile;return _persistor(m_sectionarray, tca.c_str());}~TIniAccessor(){} private: typedef std::map<TCharArray, CKeyValueArray<ValueType,bSensitive>, less> SectionArray;SectionArray m_sectionarray; public: CKeyValueArray<ValueType,bSensitive> & operator [](TCharArray charArray){if(!bSensitive) _tcsupr((TCHAR*)charArray.data());return m_sectionarray[charArray];} };
typedef TIniAccessor<> CIniAccessor;
?
文章結束給大家分享下程序員的一些笑話語錄: 自行車
一個程序員騎著一個很漂亮的自行車到了公司,另一個程序員看到了他,問 到,“你是從哪搞到的這么漂亮的車的?”
騎車的那個程序員說, “我剛從那邊過來, 有一個漂亮的姑娘騎著這個車過來, 并停在我跟前,把衣服全脫了,然后對我說,‘你想要什么都可以’”。
另一個程序員馬上說到, “你絕對做了一個正確的選擇, 因為那姑娘的衣服你 并不一定穿得了”。
--------------------------------- 原創文章 By
文件和讀取
---------------------------------
轉載于:https://www.cnblogs.com/jiangu66/archive/2013/06/01/3113075.html
總結
以上是生活随笔為你收集整理的文件读取ini文件另一种读取办法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: configparser操作配置文件
- 下一篇: 关于VC++6.0中getline函数的