17.18.實現一個讀取INI檔案的類
開發環境: vs2013, win10
經過很多次修改,和對一些錯誤的學習,才搞定了這麼一個類:
比如說LPCTSTR的賦值,new和delete要成對出現,字元陣列和字串的庫函式去取代自己寫字串處理函式等, wcsncpy_s用法,string類的賦值運算子等。
標頭檔案:
實現檔案:/* 對文字的處理要求:'='號之前強制為整數,且只允許開頭後者結尾存在空格(處理後丟棄空格),不允許存在非數字字元,否則將丟棄該鍵值對 =號右邊的value原樣儲存,包括空格的存在. 對於讀取多個ini檔案,只要修改一下,就是在loadFile函式中不要對m_map進行clear 已通過的測試樣例: 1 = abdfadfadfd ====== aaaaaa vvvv a 123 + 234 555= zzz= =dd =123 =567= ======== a=1 1234adfdd */ #pragma once #include "stdafx.h" #include<iostream> #include<fstream> #include<windows.h> #include<string> #include<map> class QueryIni { public: QueryIni(){} ~QueryIni(){} public: /** * @brief 初始化成員變數指標 * @return void */ static void Init(); /** * @brief delete成員變數指標 * @return void */ static void UnInit(); public: /** * @brief 查詢ini檔案中的鍵值,必須先呼叫SetPath,傳入路徑,再呼叫GetValue; * @param[in] const int iKey 要查詢的鍵 * @return 查詢成功返回value字串,否則返回空字串 */ static std::wstring QueryIni::GetValue(const int iKey) { wchar_t sDes[MAX_PATH + 1] = { 0 }; QueryIni::_GetInstance()->_GetValue(iKey, sDes, MAX_PATH); //TRUE,得到查詢結果 return sDes; } /** * @brief 讀取的檔案路徑 * @param[in] LPCTSTR pFilePath 讀取的檔案的路徑 * @return 是否成功載入檔案內的資料 */ static bool LoadFile(LPCTSTR pFilePath); /** * @brief 清空map中的資料 */ static void Clear(); private: static QueryIni* _GetInstance(); bool QueryIni::_RemoveSpaceAndCheckNum(std::wstring &sKey); bool _GetValue(const int iKey, wchar_t* sDes, const int len); private: std::map<int, std::wstring> m_map; static QueryIni* ms_pInstance; };
#include"stdafx.h" #include"QueryIni.h" #include <iostream> #include <fstream> #include <string> #include <codecvt> #include <locale> #include<assert.h> using namespace std; QueryIni* QueryIni::ms_pInstance = NULL; void QueryIni::Init() { if (ms_pInstance == NULL) { ms_pInstance = new QueryIni(); } } void QueryIni::UnInit() { if (ms_pInstance != NULL) { delete ms_pInstance; ms_pInstance = NULL; } } bool QueryIni::LoadFile(LPCTSTR pFilePath) { QueryIni* queryIni = QueryIni::_GetInstance(); if (pFilePath == NULL) { return false; } //這個不一定要哦! std::wifstream wFileStream(pFilePath, std::ios::binary); if (wFileStream.is_open()) { wchar_t buf[2] = {0}; wFileStream.read(buf, 2); wFileStream.clear(); wFileStream.seekg(0, ios::beg); bool isUnicode = (buf[0] == wchar_t(0xFF) && buf[1] == wchar_t(0xFE)) || (buf[0] == wchar_t(0xFE) && buf[1] == wchar_t(0xFF)) ; assert(isUnicode == true); // apply BOM-sensitive UTF-16 facet wFileStream.imbue(std::locale(wFileStream.getloc(), new std::codecvt_utf16 < wchar_t, 0x10ffff, std::consume_header >));//第二個引數是此平面將讀或寫而不出錯的wchar_t最大值 std::wstring wLine; while (std::getline(wFileStream, wLine)) { int equalPos = wLine.find_first_of(L'='); //從pos開始查詢'='第一次出現的位置 std::wstring sKey = L"", sValue = L""; if (equalPos != wstring::npos) { sKey = wLine.substr(0, equalPos); sValue = wLine.substr(equalPos + 1, wLine.length() - equalPos); if (queryIni->_RemoveSpaceAndCheckNum(sKey)) //鍵合法,插入map { int iKey = stoi(sKey); queryIni->m_map.insert(make_pair(iKey, sValue)); } } } wFileStream.close(); //開啟完檔案記得關閉 return true; } return false; } void QueryIni::Clear() { QueryIni::_GetInstance()->m_map.clear(); } QueryIni* QueryIni::_GetInstance() { if (ms_pInstance == NULL) { ms_pInstance = new QueryIni(); } return ms_pInstance; } bool QueryIni::_RemoveSpaceAndCheckNum(std::wstring &sKey) { sKey.erase(0, sKey.find_first_not_of(L" \t")); sKey.erase(sKey.find_last_not_of(L" \t") + 1); if (sKey == L"") //這是個空字串 { return false; } for (int i = 0; i < sKey.size(); i++) { if (sKey[i] > L'9' || sKey[i] < L'0') { return false; } } return true; } bool QueryIni::_GetValue(const int iKey, wchar_t* sDes, const int len) { std::map<int, std::wstring>::iterator it = m_map.find(iKey); if (it == m_map.end()) { return false; //不存在 } else { std::wstring sValue = it->second; assert(sValue.length() < len); //小心長度溢位 wcsncpy_s(sDes, len, &(sValue[0]), sValue.length()); return true; } }
至於QueryIni::GetValue(const int iKey)函式為什麼放在標頭檔案而不是在實現檔案中,參考:Windows跨模組記憶體管理的淺薄理解
使用的main函式:
#include "stdafx.h" #include<iostream> #include<fstream> #include<windows.h> #include<string> #include<map> #include <codecvt> #include"QueryIni.h" using namespace std; int _tmain(int argc, _TCHAR* argv[]) { QueryIni::Init(); QueryIni::LoadFile(L"C:\\Users\\admin\\Desktop\\test2.ini"); std::locale loc("chs");//windows下ok std::wcout.imbue(loc); std::wcout << QueryIni::GetValue(1) << std::endl; std::wcout << QueryIni::GetValue(100152) << std::endl; std::wcout << QueryIni::GetValue(102004) << std::endl; std::wcout << QueryIni::GetValue(102054) << std::endl; std::wcout << QueryIni::GetValue(100165) << std::endl; QueryIni::UnInit(); { return 0; }
相關推薦
17.18.實現一個讀取INI檔案的類
開發環境: vs2013, win10 經過很多次修改,和對一些錯誤的學習,才搞定了這麼一個類: 比如說LPCTSTR的賦值,new和delete要成對出現,字元陣列和字串的庫函式去取代自己寫字串處理函式等, wcsncpy_s用法,string類的賦值運算子等。 標頭檔案
Linux下讀取Ini檔案類
#include "Ini.h" /****************************************************************************** * 功 能:建構函式 * 參 數:無 * 返回值:無 * 備 注: *********************
【java】 一個讀取配置檔案的類
/** * <p>Title:InitConfig.java</p> * <p>Description:</p> * @author songrongkai * @date 2018年7月29日 * @version 1.0 */ p
伺服器公共庫開發--讀取ini檔案格式的類
/******************************************************************** created: 2008/07/28 filename: config.h author: Lichuang
c語言實現讀取ini檔案操作
二、實現檔案 //ini.c #include "ini.h" #include <string.h> #include <stdio.h> content* pContent; char gfilename[255]; void iniGetInt(const char* lpSe
CIniFile類,讀取INI檔案
2008年04月26日 星期六 上午 10:27/*=================================================================== 檔名:CIniFile類定義檔案
自定義讀取配置檔案類
#include<iostream> #include<string.h> #include<vector> #include<map> #include<set> #include <fstream> #include<
C# 操作INI檔案類
//補充: //using System; //using System.Runtime.InteropServices; //using System.Text; //using System.Collections;
LayaBox開發實戰之實現一個簡單的模板類
tom image nbu tex 技術分享 info fig utils gre 1.首先UI設計:記得導出 2.然後查看layaUI.max.all.js中是否生成對應UI的JS代碼: var FeedBackUI=(function(_super){
Ftp實現自動讀取本地檔案上傳到伺服器
需求:最近有個需求,類似需要將pre環境的oracle檔案,放到prd環境中hive叢集中儲存,但是因為資料來源和資料儲存節點不在一個環境中,所以無法通訊配置實現資料的直接傳輸。 解決方案: 1.寫指令碼自動將oracle中資料寫入到本地指定資料夾。 2.通過
內部類實現多繼承(內部類的優勢)及內部類實現一個介面與外圍類實現這個介面的區別
在java中一個類可以多重實現,但不能多重繼承,也就是說一個類能夠同時實現多個介面,但不能同時繼承多個類。但有時候我們確實需要繼承多個類,比如希望擁有兩個類的行為功能,就很難使用單繼承來解決問題了(當然多層繼承是可以解決的),那麼我們還可以用什麼辦法來解決多重繼承的問題呢?沒
內部類實現一個介面與外圍類實現這個介面的區別
在java中,外圍類只能繼承一個基類,要實現多繼承,只有繼承多個介面型別。有時,你需要與介面的實現進行互動,所以使用內部類最重要的一個原因是:每個內部類都能獨立的繼承自一個(介面的)實現,內部類允許你繼承多個非介面型別。正是因為內部類的這種能力,有效的實現了“多重繼承”。
使用共享記憶體實現一個程序寫檔案,兩個程序讀檔案
主要功能:讀取任意的檔案,大小不限(不超過共享記憶體設定的大小,一般為8k,但可手動重新設定,這已經很大了。),執行後兩個或多個讀程序可同時讀取該檔案並在終端列印。 要實現該功能,首先你得了解共享記憶體的搭建,有四個函式,分別為shmget,shmat,shmdt,shmc
C#操作Ini檔案類
在Windows系統中,INI檔案是很多,最重要的就是“System.ini”、“System32.ini”和“Win.ini”。該檔案主要存放使用者所做的選擇以及系統的各種引數。使用者可以通過修改INI檔案,來改變應用程式和系統的很多配置。但自從Windows
c# 賬號密碼加密, 寫入讀取ini檔案
[DllImport("kernel32")] private static extern int GetPrivateProfileString(string section, string key, string def, StringBu
用C++實現一個二叉樹類
/**//** 昨天參加宜搜的筆試,要求用C++寫一二叉樹類,實現插入,刪除,定位功能,輾轉再三,* 卻無從下手,甚急,終基礎不好,今天再想,通過層次遍歷二叉樹,再進行實現相關功能* 實也不難. 以下程式碼*//**//** FileName:BTree.cpp* Description:binary tre
Java讀取ini檔案的值
IniFile iniFile=new BasicIniFile(); File f = new File(""); String cf = null; cf = f.getCanonicalPath(); File file=new File(c
SpringMVC 實現POI讀取Excle檔案中資料匯入資料庫(上傳)、匯出資料庫中資料到Excle檔案中(下載)
package com.shiliu.game.utils; import java.io.OutputStream; import java.net.URLEncoder; import java.util.ArrayList; import java.util.List; import
用Python實現一個簡單的檔案傳輸協議
寫個東西並非無聊或者練手,而是厭煩了每次都得重頭寫。我已經不是第一次碰到下面的情況:遠端到一臺可以連線內網的機器,結果發現其環境極為惡劣,沒有scp。最誇張的一次,我見過一臺機器連man都沒裝。所幸裝了ssh可以讓我遠端。但沒有scp怎麼傳檔案呢?ftp?試了幾個命令,沒有
Python實現一個二叉樹類
最近在學習Python,之前只是在寫指令碼,做一些資料處理的工作,今天開始看Python的面向物件,熟悉了語法之後,想實現一個二叉樹類練練手。 以前寫C++比較多,用Python寫二叉樹好不習慣,沒有指標,沒有引用!!! 所以我就遇到了一下幾個問題: 1、該怎麼把二叉樹各