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

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

文件读取ini文件另一种读取办法相关推荐

  1. 使用 sed / shell 读取 ini 文件

    使用 sed / shell 读取 ini 文件 动机 我决定编写一个脚本来进行干净的 macOS (BSD) / Linux 的初始设置. 我认为有一个 tsukkomi 说"现在大多数发 ...

  2. C# 读取ini文件 百度问问学习文档

    C# 读取ini文件 10 有多个section,现想读取整个ini文件和指定section下所有内容 补充: 发布答案可以,请对准题目啊,我不要指定节点的内容,我知道!我要的是读取指定区域的内容,假 ...

  3. ASP读取ini文件的实现方法

    INI是微软Windows操作系统中的文件扩展名.这些字母表示初始化.正如该术语所表示的,INI文件被用来对操作系统或特定程序初始化或进行参数设置.ini文件可以存储很多数据,用来配置应用软件以实现不 ...

  4. VS2017读取ini 文件中文乱码

    [说明] 今天写项目的时候,读取ini文件时候,中文就是乱码了. 测试过,直接输出中文,是没有问题的. 因此问题就确定了是在文件的编码上. (建议各位也像我这么测试下,不然这个解决方案不一定帮得了你) ...

  5. VS VC 读取 INI文件

    1.获取应程序同极目录下的config.ini路劲void GetConfigFilePath(char *path,int len, char *file) {char module[256] = ...

  6. C++读取ini文件的类

    C++读取ini文件的类 取自:http://www.viksoe.dk/code/all_mfc.htm,里面有各种MFC常用的类 // Ini.h: interface for the CIni ...

  7. java inireader_用Java读取INI文件(带section的)

    代码 #include #include int main(){ boost::property_tree::ptree m_pt, tag_setting; read_ini("confi ...

  8. Qt读取ini文件中文乱码问题

    Qt读取ini文件中文乱码问题 方法1: QSettings settings("xxxx.ini",QSettings::IniFormat); settings.setIniC ...

  9. VB6读取INI文件

    开发环境:VB6 程式版本更新, 读取INI文件做对比, 确认版本是否最新. 可用VB6的工具下的API检视员来自动生成API调用代码. INI文件内容: [Version] TEST=2017-11 ...

  10. QSettings读取ini文件,中文key方法

    (吐槽:什么鬼,为啥要用中文当key???我也不知道呀) QSettings读取ini文件,其中key是中文的.例如: [单位] 1=运维检修部1(检修公司) 2=运维检修部2(检修公司)[班组] 1 ...

最新文章

  1. 生成html页面的ftl文件,FreeMarker生成静态HTML页面的工具类FreeMarkerUtil
  2. MVC5中EF6 Code First启动慢及间隙变慢的一些优化处理
  3. Oracle SQL中实现indexOf和lastIndexOf功能
  4. 发个自己的CSS重置基础代码
  5. nuxt解决首屏加载慢问题_如何解决百度云盘下载速度慢的问题
  6. Mybatis入门-关联查询(八)
  7. deepin应用分发_Deepin Dock隐藏功能等功能说明
  8. 关于打印数组一直输出地址符号的一个解决方法
  9. delphi switch语句例子_Python系列之常用语句
  10. 自称世界上最权威监控软件FlexiSpy被黑删库,怎么做到的?
  11. 一篇关于arc下内存管理的老文章,包含各种冷门修饰符(关于内存),写的较好,mark...
  12. 台式机设成仅计算机,如何把台式电脑设置成wifi热点
  13. 系统动力学学习笔记一
  14. 甘超波:NLP表象系统
  15. 由ERA5逐小时数据获取逐日数据——三种方法
  16. Java Test Fore
  17. android访问win10共享文件夹,手机怎么用ES浏览器访问Win10共享文件教程
  18. Matlab透视变换
  19. 无线网络现状与发展趋势
  20. Java数据结构之中缀表达式转后缀表达式

热门文章

  1. thinkphp使用echarts_Thinkphp 与Echarts-php 使用
  2. java 对象克隆_JAVA对象克隆
  3. 剑指offer:12-17记录
  4. 关系数据库——mysql数据类型大总结
  5. 树状数组维护区间和的模型及其拓广的简单总结
  6. python学习实例(3)
  7. Mat矩阵(图像容器)的创建及CV_8UC1,CV_8UC2等参数详解
  8. PaperNotes(10)-Maximum Entropy Generators for Energy-Based Models
  9. Python中yield简单用法
  10. python语言print函数_Python 的 print 函数