文件读取ini文件另一种读取办法

时间紧张,先记一笔,后续优化与完善。

    Windows下的ini文件的读取可以应用系统提供的api来实现

    

    GetPrivateProfileString

    GetPrivateProfileInt

    ...

    现实应用中, 如果不应用一种同一的方法来包装一下会让源代码看起来很乱。

    所以,须要计划一个便利,雅观,直观的配置文件操作类!

    

    准则是代码难看,轻易维护

    

    需求:

    直观的调用形式

    实现潜规则

    满足各类数据(实现api经常应用的数据类型)

    

    

解释:

    

  • 直观的调用形式是什么意思
    以减少键盘输入和见文知意为准则的计划方式,把长函数名变为符号。用符号来表示操作
  • 潜规则
    在配置ini访问中的潜规则是
    1. Wiki上对ini的定义
        INI文件有节的观点节用 [] 包围,类似数据中的表名称,如
    [startup]

        名称/值对,类似数据库表中的字段,如
    TargetIP=10.0.0.1

        注释, 以";"为注释的开始,到行尾,如
    MenuOne=File...    ; 菜单的第一项文字描述

    2. Windows系统中操作ini文件时有#扫尾的行是疏忽的,如:
    #对打印机的设置

3. 可配置是否疏忽Key的大小写
4. 符合语义的读取和写入
在windows api下GetPrivateProfile/WritePrivateProfileXXXX在调用该方法时同步执行对ini文件的操作
  • 满足各类数据,在ini中经常应用的数据有两种,字符串整型数据,满足所有数据类型明显不现实,可以在之后根据不同须要进行扩展
计划应用方法:
1.  读取
CIniAccessor accessor(_T("config.ini"));
std::wstring strMenuOne = accessor[_T("startup")][_T("MenuOne")](_T("DefaultMenuItem"));
2. 写入
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();      // 写入磁盘



    

上面是数据结构
每日一道理
无知者为梦想中的虚幻而苦苦等待,换回的不是所求的,而是岁月在脸上留下的印痕,一事无成的人一生便是虚度。生活中,与其花时间去等待,不如加快步伐去追寻理想,试着与时间赛跑,也许身躯、心理会感到劳累,但这样的生活毕竟是充实的。
  1. 基础类
    typedef struct tagAccessorData
    {union VALUETYPE{LONG longValue;TCHAR * pszValue;}value;enum{TYPE_EMPTY, TYPE_LONG, TYPE_CHAR}valuetype;tagAccessorData():valuetype(TYPE_EMPTY){}
    }ACCESSORDATA;



  2. 辅助工具类
    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;}
    };


  3. 访问类
    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];}
    };
  4. 访问类
    typedef TIniAccessor<> CIniAccessor;


 

 

文章结束给大家分享下程序员的一些笑话语录: 自行车
一个程序员骑着一个很漂亮的自行车到了公司,另一个程序员看到了他,问 到,“你是从哪搞到的这么漂亮的车的?”
骑车的那个程序员说, “我刚从那边过来, 有一个漂亮的姑娘骑着这个车过来, 并停在我跟前,把衣服全脱了,然后对我说,‘你想要什么都可以’”。
另一个程序员马上说到, “你绝对做了一个正确的选择, 因为那姑娘的衣服你 并不一定穿得了”。

--------------------------------- 原创文章 By
文件和读取
---------------------------------

转载于:https://www.cnblogs.com/jiangu66/archive/2013/06/01/3113075.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/461025.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

浅谈mysql数据库引擎

2019独角兽企业重金招聘Python工程师标准>>> 数据库是数据的集合&#xff0c;计算机中的数据库是存储器上一些文件的集合或者是内存数据的集合。Mysql,SQL server数据库都是可以存储数据&#xff0c;并提供数据查询&#xff0c;更新功能的数据库管理系统。Mysql数据…

网络摄像机简介

以下内容源于网络资源的学习与整理&#xff0c;如有侵权请告知删除。 一、网络摄像机定义 &#xff08;1&#xff09;网络摄像机&#xff0c;也叫IP摄像机&#xff0c;即IPCamera&#xff0c;简称IPC&#xff0c;近几年得益于网络带宽&#xff0c;芯片技术&#xff0c;算法技术…

如今的移动操作系统,写在2013年——android篇 by 伊一线天

前奏&#xff1a; 曾在2011年&#xff0c;我写过一篇同样题材的文章。时隔2年后&#xff0c;如今的移动操作系统领域跌宕起伏&#xff0c;2年前的一些系统变得更加强大&#xff0c;一些已经昙花一现。现在让我再来总结一些2013年移动操作系统。 第一讲&#xff1a;android 自从…

linux qt ping,Qt5.2中使用ping命令实现Ip扫描功能

在实现类似于Free IP Scanner 2.1的Ip扫描器软件中&#xff0c;会用到ping命令。如果使用Qt编程实现&#xff0c;主要会用QThread、QProcess这两个类。关于这两个类的具体用法可以查阅Qt助手或者QT官网。在QT中为了扫描大量的Ip&#xff0c;通常需要将扫描Ip的任务放在一个单独…

Python安装模块出错(ImportError: No module named setuptools)解决方法

原地址&#xff1a;http://www.cnblogs.com/BeginMan/archive/2013/05/28/3104928.html 在window平台下安装第三方模块时&#xff0c;出现这样的错误&#xff1a; Google了以下&#xff0c;才知道原来Python里少了这个模块。 我们可以在Python官网去查找 其中 Package Index中查…

kali linux 2.0 ssh,Kali 2.0使用SSH进行远程登录(示例代码)

一、配置SSH参数修改sshd_config文件&#xff0c;命令为&#xff1a;vim /etc/ssh/sshd_config将#PasswordAuthentication no的注释去掉&#xff0c;并且将NO修改为YES //kali中默认是yes将PermitRootLogin without-password修改为PermitRootLogin yes二、启动SSH服务命令为&am…

数据库课程设计报告

课程设计报告内容 封面&#xff08;注明组员及分工&#xff09; 目录 1&#xff0e;系统概述 – 系统的特点 – 系统设计环境 2&#xff0e;系统需求分析 – 系统设计的目标 – 系统需求分析&#xff08;给出&#xff1a;数据流图、数据字典&#xff09; – 系统功能…

基于Hi3516A的H265 IPC LIVE555 开发

转载于http://m.blog.csdn.net/faihung/article/details/73008742&#xff0c;如有侵权请告知删除。 1 系统工作原理 系统以Hi3516A开发平台&#xff08;由高分辨率1080 p的AR0330摄像头模块、带千兆以太网功能的Hi3516A控制器模块组成硬件平台&#xff0c;并在硬件平台上烧写了…

教材配套PPT初稿

1&#xff0d;10章初稿&#xff0c;基本完整。有些粗糙&#xff0c;后面可能会稍作调整。 附更新情况如下&#xff1a; 1.增加了第10章内容&#xff1b; 2.第5章增加了一些内容&#xff1b; 3.第3章内容部分更新&#xff1b; 4.增加了第8&#xff0d;9章内容。 订正&#xff1a…

linux ssh抓包,如何在SSH连接Linux系统的环境下使用wireshark抓包?

TSINGSEE青犀视频云边端架构EasyNVR、EasyDSS、EasyGBS等都是有两种操作系统的版本&#xff0c;一种是linux&#xff0c;一种是windows。而大多数开发者用户都会使用linux版本进行安装。对于安装部署出现的问题&#xff0c;TSINGSEE青犀视频团队研发的经常为客户远程调试&#…

Gearman 启动日志文件提示协议出错的BUG

如果直接以gearmand -d 启动 /usr/local/var/log/gearmand.log 里提示 Address family not supported by protocol ERROR 2014-11-20 20:05:49.000000 [ main ] socket()(Address family not supported by protocol) -> libgearman-server/gearmand.cc:468 ERROR 2014-11-20…

linux环境变量设置方法(PATH等环境变量)

以下内容源于网络资源的学习与整理&#xff0c;如有侵权请告知删除。 linux系统的环境变量有很多&#xff0c;这里简单介绍几个常见环境变量的设置方法。 环境变量PATH 这个环境变量&#xff0c;表示“可执行程序的查找路径”。 1、查看PATH的值&#xff0c;输入“echo $PATH”…

ASP.NET后台调用前台JS函数的三种常见方法

为什么80%的码农都做不了架构师&#xff1f;>>> 第一种&#xff1a;使用普通的添加控件中的Attributes属性进行调用 例如&#xff0c;像一般的普通的按钮&#xff1a;Button1.Attributes.Add("onclick","MyFun();"); 此方法只能在Onload中或者…

Android基础知识大纲

原文链接&#xff1a;http://android.eoe.cn/topic/overview * Android是什么&#xff1f;*版本&#xff1a;Android 4.0 r1原始页面&#xff1a;http://developer.android.com/guide/basics/what-is-android.htmlAndroid是一个移动设备的程序集合&#xff0c;包括的操作系统、…

linux unix shell programming,UnixampLinux Shell Programming I.ppt

《Unix&ampLinux Shell Programming I.ppt》由会员分享&#xff0c;可在线阅读&#xff0c;更多相关《Unix&ampLinux Shell Programming I.ppt(17页珍藏版)》请在人人文库网上搜索。1、Unix/Linux Shell Programming I,Dec 14th 2011 Shen Wei,Agenda,Unix/Linux Intro…

被遮挡的绝对定位 z-index

<div class”A” style”position:relative;”>A (relative) <div class”logo” style”position:absolute;z-index:99999;“></div> </div> <div class”B” style”position:relative;”>B (relative)</div> 最近做minisite项目时&…

嵌入式数据库sqlite在ARM上的的移植和使用

参考SQLite的编译、安装和使用_whz_zb的博客-CSDN博客&#xff0c;如有侵权&#xff0c;请告知删除。 参考&#xff1a;头文件路径问题 Linux下的头文件搜索路径 - 心哲 - 博客园 参考&#xff1a;进一步学习资源 SQlite - 标签 - likebeta - 博客园 一、源码获取 SQLite Do…

贪心法

贪心法的证明 —归纳证明&#xff1a; —贪心法使用的条件是&#xff1a;最优子结构和贪心选择正确性 —贪心算法是一步一步实现的&#xff0c; —在归纳证明的时候&#xff0c;贪心的第一步贪心选择策略的正确性就是归纳基础&#xff0c;因为以后都是一个子问题的选取&#xf…

第一季5:Hi3518EV200的环境搭建

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 一、内容总结 本文讲述如何安装交叉编译工具链&#xff0c;与编译源码得到uboot、kernel、rootfs镜像文件。 &#xff08;1&#xff09;安装交叉编译工具链&#xff0c;主要是通过执行osdrv/opensou…

Linux下WPS自主设置快捷键,电脑wps的word怎么自主设定快捷键

打开Word2003&#xff0c;点击“工具”选项卡&#xff0c;在下拉菜单中选择“自定义”栏。在弹出的“自定义”页面框中选择“键盘”。在弹出的“自定义键盘”页面框中选择你要设置快捷的命令&#xff0c;比如办公族在这里选择了“字体”里的“幼圆体”这个命令当前并没有快捷键…