17.18.实现一个读取INI文件的类
来源:互联网 发布:java虚拟机教程 编辑:程序博客网 时间:2024/06/06 21:06
开发环境: vs2013, win10
经过很多次修改,和对一些错误的学习,才搞定了这么一个类:
比如说LPCTSTR的赋值,new和delete要成对出现,字符数组和字符串的库函数去取代自己写字符串处理函数等, wcsncpy_s用法,string类的赋值运算符等。
头文件:
/*对文本的处理要求:'='号之前强制为整数,且只允许开头后者结尾存在空格(处理后丢弃空格),不允许存在非数字字符,否则将丢弃该键值对=号右边的value原样保存,包括空格的存在.对于读取多个ini文件,只要修改一下,就是在loadFile函数中不要对m_map进行clear已通过的测试样例:1= abdfadfadfd======aaaaaavvvva123 + 234555=zzz==dd=123=567=========a=11234adfdd*/#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 facetwFileStream.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下okstd::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;}
阅读全文
0 0
- 17.18.实现一个读取INI文件的类
- ASP读取ini文件的实现方法
- Ini文件的读取
- INI文件的读取
- INI文件的读取
- ini文件的读取
- 如何读取一个.ini文件
- 一个读取INI配置文件的类
- Ini文件读取类
- ini文件读取类
- 轻松实现一个操作ini文件的类
- 轻松实现一个操作ini文件的类
- 轻松实现一个操作ini文件的类
- 【转】轻松实现一个操作ini文件的类
- 轻松实现一个操作ini文件的类
- 轻松实现一个操作ini文件的类
- 轻松实现一个操作ini文件的类
- 轻松实现一个操作ini文件的类
- 每天一点小知识【7】—Android7.0新特性
- opencl之code builder学习教程4
- 为 MariaDB 配置远程访问权限
- js 回调函数
- maven+ssm+oracle简单项目搭建
- 17.18.实现一个读取INI文件的类
- BZOJ3196 二逼平衡树(线段树套线段树)
- Android----沉浸式
- Cookie&session
- python-day1
- 数字信号处理——卷积
- BoundGeoOperations里面的redis操作
- STL之vector容器详解
- tensorflow placeholder()