Ini文件读取类,采用C++ STL实现

2023-11-13

背景:编程过程中经常会遇到读取Ini文件的场合,封装一个方便的类,能否避免重复编写,以后可复用。ini文件的格式很简单,并且不像xml之类的配置文件严谨。通常用于配置简单的键值对。
本类测试文件如下:<server.ini>

[plain]  view plain copy
  1. #what  
  2. [server1]  
  3.  ip= 192.168.1.1  
  4. port=8888  
  5. type=ai  
  6.   
  7. #no  
  8. [server2]  
  9. ip=10.10.10.10  
  10. port=5002  
  11. type=move  
  12.   
  13. #shit  
  14. [server3]  
  15. ip=127.0.0.1  
  16. port=9527  
  17. type=cache  

[cpp]  view plain copy
  1. /*********************头文件   inifile.h *********************************/  
  2. <pre name="code" class="cpp">#ifndef _INI_FILE_  
  3. #define _INI_FILE_  
  4.   
  5. #include <string>  
  6. #include <map>  
  7. #include <iostream>  
  8.   
  9. using namespace std;  
  10.   
  11. #define MAX_LINE_BUF_SIZE               80  
  12. #define MAX_SECTION_CONTEXT_BUF_SIZE    40  
  13. #define MAX_KEY_SIZE                    40  
  14. #define MAX_VALUE_SIZE                  40  
  15.   
  16. class IniFile  
  17. {  
  18.     typedef std::map< string, string > MapKeyValue;  
  19.     typedef map< string, MapKeyValue > MapSection;  
  20.   
  21. public:  
  22.     IniFile();  
  23.     ~IniFile();  
  24.   
  25.     bool Init(char* szFileName);  
  26.     void Save();  
  27.     bool SaveAs(char* szFileName);  
  28.     void ShowFileContext();  
  29.   
  30.     string GetValue(const string& strKey);  
  31.     string GetValueFromSection(const string& strSection, const string& strKey);  
  32.   
  33.     int GetInt(const string& strKey);  
  34.     float GetFloat(const string& strKey);  
  35.   
  36. private:  
  37.     void DelInvalidSign(char* szOldLine, char* szNewLine);  
  38.     bool IsNoteLine(char* szLine);  
  39.     bool IsEmptyLine(char* szLine);  
  40.     bool IsNewSection(char* szLine);  
  41.     bool IsKeyValueLine(char* szLine);  
  42.   
  43.     bool GetNewSectionContext(char* szLine, string& strNewSectionContext);  
  44.     bool GetKeyValue(char* szLine, string& strKey, string& strValue);  
  45.   
  46. private:  
  47.     string m_strFileName;  
  48.     MapSection m_mapSection;  
  49. };  
  50.   
  51. #endif</pre><br>  
  52. <pre></pre>  
  53. <pre name="code" class="cpp">/***************实现文件  inifile.cpp******************/  
  54. <pre name="code" class="cpp">#include "inifile.h"  
  55.   
  56. IniFile::IniFile( )  
  57. {  
  58.   
  59. }  
  60.   
  61. IniFile::~IniFile()  
  62. {  
  63.   
  64. }  
  65.   
  66. bool IniFile::Init( char* szFileName )  
  67. {  
  68.     if (NULL == szFileName || strlen(szFileName) == 0)  
  69.     {  
  70.         return false;  
  71.     }  
  72.   
  73.     m_strFileName = szFileName;  
  74.   
  75.     FILE* pFile = fopen( szFileName, "rb" );  
  76.     if (NULL == pFile)  
  77.     {  
  78.         return false;  
  79.     }  
  80.   
  81.     char szReadLineBuf[MAX_LINE_BUF_SIZE];  
  82.     char szLineBuf[MAX_LINE_BUF_SIZE];  
  83.     string strCurSection;  
  84.     string strKey;  
  85.     string strValue;  
  86.     while(NULL != fgets(szReadLineBuf, MAX_LINE_BUF_SIZE, pFile))  
  87.     {  
  88.         DelInvalidSign(szReadLineBuf, szLineBuf);  
  89.   
  90.         if (IsNoteLine(szLineBuf) || IsEmptyLine(szLineBuf))  
  91.         {  
  92.             continue;  
  93.         }  
  94.         else if (IsNewSection(szLineBuf))  
  95.         {  
  96.             GetNewSectionContext(szLineBuf, strCurSection);  
  97.         }  
  98.         else if (IsKeyValueLine(szLineBuf))  
  99.         {  
  100.             GetKeyValue(szLineBuf, strKey, strValue);  
  101.             m_mapSection[strCurSection][strKey] = strValue;  
  102.         }  
  103.         else  
  104.         {  
  105.             continue;  
  106.         }  
  107.     }  
  108.   
  109.     return true;  
  110. }  
  111.   
  112. bool IniFile::IsNoteLine( char* szLine )  
  113. {  
  114.     return (szLine[0] == '#');  
  115. }  
  116.   
  117. bool IniFile::IsEmptyLine( char* szLine )  
  118. {  
  119.     int nLineSize = strlen(szLine);  
  120.   
  121.     if (nLineSize == 0)  
  122.     {  
  123.         return true;  
  124.     }  
  125.     else  
  126.     {  
  127.         return false;  
  128.     }  
  129. }  
  130.   
  131. bool IniFile::IsNewSection( char* szLine )  
  132. {  
  133.     return (strchr(szLine, '[') && strchr(szLine, ']'));  
  134. }  
  135.   
  136. bool IniFile::IsKeyValueLine( char* szLine )  
  137. {  
  138.     return (NULL != strchr(szLine, '='));  
  139. }  
  140.   
  141. bool IniFile::GetNewSectionContext( char* szLine, string& strNewSectionContext )  
  142. {  
  143.     char szSectionContextBuf[MAX_SECTION_CONTEXT_BUF_SIZE] = {0};  
  144.     strNewSectionContext.clear();  
  145.   
  146.     char* pSectionContextBegin = strchr(szLine, '[');  
  147.     char* pSectionContextEnd = strchr(szLine, ']');  
  148.     int nSectionContextLen = pSectionContextEnd - pSectionContextBegin - 1;  
  149.   
  150.     memcpy_s(szSectionContextBuf, MAX_SECTION_CONTEXT_BUF_SIZE, pSectionContextBegin + 1, nSectionContextLen);  
  151.     strNewSectionContext = szSectionContextBuf;  
  152.   
  153.     return true;  
  154. }  
  155.   
  156. bool IniFile::GetKeyValue( char* szLine, string& strKey, string& strValue )  
  157. {  
  158.     strKey.clear();  
  159.     strValue.clear();  
  160.   
  161.     char* pEqualPos = strchr(szLine, '=');  
  162.     char szKeyBuf[MAX_KEY_SIZE] = {0};  
  163.     char szValueBuf[MAX_VALUE_SIZE] = {0};  
  164.     int nKeyLen = pEqualPos - szLine;  
  165.     int nValueLen = strlen(szLine) - nKeyLen - 1;  
  166.   
  167.     memcpy_s(szKeyBuf, MAX_KEY_SIZE, szLine, nKeyLen);  
  168.     strKey = szKeyBuf;  
  169.   
  170.     memcpy_s(szValueBuf, MAX_VALUE_SIZE, pEqualPos + 1, nValueLen);  
  171.     strValue = szValueBuf;  
  172.       
  173.     return true;  
  174. }  
  175.   
  176. void IniFile::Save()  
  177. {  
  178.   
  179. }  
  180.   
  181. bool IniFile::SaveAs( char* szFileName )  
  182. {  
  183.     if (NULL == szFileName || strlen(szFileName) == 0)  
  184.     {  
  185.         return false;  
  186.     }  
  187.   
  188.     FILE* pFile = fopen(szFileName, "w");  
  189.     if (NULL == pFile)  
  190.     {  
  191.         return false;  
  192.     }  
  193.   
  194.     // 写入文件内容  
  195.     MapSection::iterator itSection = m_mapSection.begin();  
  196.     for (; itSection != m_mapSection.end(); itSection++)  
  197.     {  
  198.         MapKeyValue& refKeyValueMap = itSection->second;  
  199.   
  200.         fprintf(pFile, "[%s]\n", itSection->first.c_str());  
  201.   
  202.         MapKeyValue::iterator itKV = refKeyValueMap.begin();  
  203.         for (; itKV != refKeyValueMap.end(); itKV++)  
  204.         {  
  205.             fprintf(pFile, "%s=%s\n", itKV->first.c_str(),  itKV->second.c_str());  
  206.         }  
  207.   
  208.         fprintf(pFile, "\n");  
  209.     }  
  210.   
  211.     return true;  
  212. }  
  213.   
  214. void IniFile::ShowFileContext()  
  215. {  
  216.     MapSection::iterator itSection = m_mapSection.begin();  
  217.     for (; itSection != m_mapSection.end(); itSection++)  
  218.     {  
  219.         MapKeyValue& refKeyValueMap = itSection->second;  
  220.         cout << "==============================" << endl;  
  221.         cout << "Section:" << itSection->first << endl;  
  222.   
  223.         MapKeyValue::iterator itKV = refKeyValueMap.begin();  
  224.         for (; itKV != refKeyValueMap.end(); itKV++)  
  225.         {  
  226.             cout << itKV->first << " = " << itKV->second << endl;  
  227.         }  
  228.         cout << "==============================" << endl;  
  229.         cout << endl;  
  230.     }  
  231. }  
  232.   
  233. void IniFile::DelInvalidSign( char* szOldLine, char* szNewLine )  
  234. {  
  235.     int iOldLineLen;  
  236.     if (NULL == szOldLine || (iOldLineLen = strlen(szOldLine)) == 0)  
  237.     {  
  238.         return;  
  239.     }  
  240.   
  241.     char tmpChar;  
  242.     int nNewLineIndex = 0;  
  243.     for (int i = 0; i < iOldLineLen; i++)  
  244.     {  
  245.         tmpChar = szOldLine[i];  
  246.         if (tmpChar == ' '  
  247.             || tmpChar == '\t'  
  248.             || tmpChar == '\r'  
  249.             || tmpChar == '\n')  
  250.         {  
  251.             continue;  
  252.         }  
  253.   
  254.         szNewLine[nNewLineIndex++] = tmpChar;  
  255.     }  
  256.   
  257.     szNewLine[nNewLineIndex] = 0;  
  258. }  
  259.   
  260. std::string IniFile::GetValue( const string& strKey )  
  261. {  
  262.     MapSection::iterator itSection = m_mapSection.begin();  
  263.     for (; itSection != m_mapSection.end(); itSection++)  
  264.     {  
  265.         MapKeyValue& refKeyValueMap = itSection->second;  
  266.         MapKeyValue::iterator itKV = refKeyValueMap.find(strKey);  
  267.         if (itKV != refKeyValueMap.end())  
  268.         {  
  269.             return itKV->second;  
  270.         }  
  271.     }  
  272.   
  273.     return "";  
  274. }  
  275.   
  276. std::string IniFile::GetValueFromSection( const string& strSection, const string& strKey )  
  277. {  
  278.     MapSection::iterator itSection = m_mapSection.find(strSection);  
  279.     if (itSection == m_mapSection.end())  
  280.     {  
  281.         return "";  
  282.     }  
  283.   
  284.     MapKeyValue& refKeyValueMap = itSection->second;  
  285.     MapKeyValue::iterator itKV = refKeyValueMap.find(strKey);  
  286.     if (itKV != refKeyValueMap.end())  
  287.     {  
  288.         return itKV->second;  
  289.     }  
  290.   
  291.     return "";  
  292. }  
  293.   
  294. int IniFile::GetInt( const string& strKey )  
  295. {  
  296.     string str = GetValue(strKey);  
  297.   
  298.     return atoi(str.c_str());  
  299. }  
  300.   
  301. float IniFile::GetFloat( const string& strKey )  
  302. {  
  303.     string str = GetValue(strKey);  
  304.   
  305.     return atof(str.c_str());  
  306. }  
  307.   
  308. //因为配置文件中记录的数据均以字符串形式独处,可以根据需要获取的数据类型,自行定义Get***类型的函数集</pre><br>  
  309. // 测试用代码  
  310. <pre></pre>  
  311. <pre name="code" class="cpp">#include "inifile.h"  
  312. #include <iostream>  
  313.   
  314. using namespace std;  
  315.   
  316. int main(int argc, char* argv[])  
  317. {  
  318.   
  319.     IniFile file;  
  320.   
  321.     if (!file.Init("server.ini"))  
  322.     {  
  323.         return -1;  
  324.     }   
  325.       
  326.     // 现实配置文件的全部内容  
  327.     file.ShowFileContext();  
  328.   
  329.     cout << file.GetInt("port") << endl;  
  330.     cout << file.GetValueFromSection("server2","ip") << endl;  
  331.       
  332.   
  333.     // 将文件另存为  
  334.     //file.SaveAs("heihei.ini");  
  335.   
  336.     return 0;  
  337. }</pre><br>  
  338. <br>  
  339. <br>  
  340. <br>  
  341. <br>  
  342. <p></p>  
  343. <map></map>  
  344. <pre></pre>  
  345. <pre></pre>  
  346.   
  347. </pre>  
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Ini文件读取类,采用C++ STL实现 的相关文章

  • 如何使用 ASP.NET MVC 进行 HTTP 调用?

    我正在尝试做的事情 我试图练习进行 HTTP 调用 如果这就是它的名字 来自一个简单的 ASP NET MVC Web 应用程序 为此 我尝试从以下位置获取天气详细信息打开天气地图 http openweathermap org appid
  • 中间件 API 的最佳实践是什么? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我们正在开发一个中间件 SDK 采用 C 和 Java 语言 供游戏开发人员 动画软件开发人员 阿凡达开
  • OpenCV Visual Studio ntdll.dll

    我尝试在 Visual Studio 2013 上使用 OpenCV 2 4 10 创建一个项目 但由于以下异常 到目前为止我运气不佳 请建议帮助 TIA letstryitonemoretime exe Win32 Loaded C Us
  • 如何在 MFC 中调整对话框大小时移动控件?

    我已经在 MFC 中创建了对话框视图 从下图中可以清楚地看到 如滑块控件和编辑框等 当我调整对话框大小时 这些控件不会移动 在此输入图像描述 https i stack imgur com 7OxAK jpg 我想移动控件以适应对话框 但不
  • C++ 中的单例和抽象基类

    最近我遇到了关于实现 Singleton 但涉及抽象基类的问题 假设我们有这样的类层次结构 class IFoo it s ABC class Foo public IFoo 我们的单例类定义如下 template
  • 我们如何将数据从一个打开的表单传递到另一个打开的表单?

    winform中如何将数据从一个窗体传递到另一个打开的窗体 在 Windows 应用程序中 一个窗体打开另一个窗体 当我在父表单中输入一些数据时 这些数据将立即反映在另一个子表单中 这将如何发生 取决于你想要多花哨 最简单的方法就是直接调用
  • 'goto *foo' 其中 foo 不是指针。这是什么?

    我正在玩标签作为值 https gcc gnu org onlinedocs gcc Labels as Values html并最终得到这段代码 int foo 0 goto foo 我的 C C 经验告诉我 foo means dere
  • async wait 在调用异步方法时返回 Task> 而不是 List

    我正在尝试了解 async wait 的用法 并且研究了一些博客文章 现在我已经编写了一个测试代码 但它没有按照我期望的方式工作 我有一个返回列表的方法 private List
  • 如何在 C++ 中对静态缓冲区执行字符串格式化?

    我正在处理一段对性能要求非常高的代码 我需要执行一些格式化的字符串操作 但我试图避免内存分配 甚至是内部库的内存分配 在过去 我会做类似以下的事情 假设是 C 11 constexpr int BUFFER SIZE 200 char bu
  • 以标准用户身份打开默认浏览器 (C++)

    我目前正在使用 ShellExecute 打开 在用户浏览器中打开 URL 但在 Win7 和 Vista 中遇到了一些麻烦 因为该程序作为服务运行提升 当 ShellExecute 打开浏览器时 它似乎读取 本地管理员 配置文件而不是用户
  • 枚举器上的 [[maybe_unused]]

    查看规格 maybe unused http en cppreference com w cpp language attributes 它指出 出现在类 typedef 变量 非静态数据成员 函数 枚举或枚举器的声明中 如果编译器对未使用
  • 套接字:监听积压并接受

    listen sock backlog 在我看来 参数backlog限制连接数量 这是我的测试代码 server initialize the sockaddr of server server sin family AF INET ser
  • Create CFrameWnd 给出了第一次机会异常——为什么?

    我正在尝试使用基于 CFrameWnd 的代码编写一个简单的 MFC 应用程序 该应用程序在可滚动窗口中绘制 下面的代码改编自 Prosise Programming Windows with MFC 第 2 版 第 89ff 页 当我在调
  • .Net Core 中的脚手架以及解决方案中的多个项目

    我创建了一个针对 net461 的 Net Core MVC6 应用程序 我使用了一个我非常熟悉的项目结构 其中我将数据 模型和服务类放置在单独的类库项目中 并且 Web 项目引用这些项目 当我尝试搭建控制器时 我收到一条错误 指出我正在搭
  • std::string 在 Visual Studio 上的具体行为?

    我有一个项目需要读取 写入大文件 我决定使用 ifstream read 将这些文件一次性放入内存中 放入 std string 中 这似乎是在 C 中执行此操作的最快方法 http insanecoding blogspot com 20
  • 为什么 std::ranges::filter_view 对象必须是非常量才能查询其元素?

    include
  • 如何使用 libpq 获取双精度值?

    The examples http www postgresql org docs 9 3 interactive libpq example htmllibpq 文档中展示了如何通过将整数值转换为主机字节序表示来获取整数值 我很好奇必须做
  • Qt:将拖放委托给子级的最佳方式

    我在 QWidget 上使用拖放 我重新实现了 DragEnterEvent dragLeaveEvent dragMoveEvent 和 dropEvent 效果很好 在我的 QWidget 中 我有其他 QWidget 子级 我希望它们
  • 需要使用 openssl 加密和解密文件的示例 C 代码

    我正在用 Linux C 编写代码 我需要使用以下命令来加密和解密文件 openssl 目前 我使用系统命令 des3 e nosalt k 0123456789012345 in inp file out out file 进行加密 使用
  • 如何将 char 转换为 unsigned int?

    我有一个字符数组 它实际上用作字节数组 而不是用于存储文本 在数组中 有两个特定字节表示我需要存储到无符号 int 值中的数值 下面的代码解释了设置 char bytes bytes 2 bytes 0 0x0C For the sake

随机推荐

  • Linux OpenGauss 数据库远程连接

    目录 前言 1 Linux 安装 openGauss 2 Linux 安装cpolar 3 创建openGauss主节点端口号公网地址 4 远程连接openGauss 5 固定连接TCP公网地址 6 固定地址连接测试 前言 openGaus
  • carla二次开发(一)自定义创建地图

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 为什么创建carla地图很困难 二 官方创建方法 三 blender插件创建地图 四 City Engine创建地图 五 ue4创建地图 前言 carla
  • 某A类网络10.0.0.0的子网掩码255.224.0.0,请确定可以划分的子网个数,写出每个子网的子网号及每个子网的主机范围。

    某A类网络10 0 0 0的子网掩码255 224 0 0 请确定可以划分的子网个数 写出每个子网的子网号及每个子网的主机范围 可以确定划分的子网有2 3 2 6个 子网号 10 32 0 0主机范围 10 32 0 1 10 63 255
  • 数据结构计算题

    1 将下列函数按它们在 n 时的无穷大阶数 从小到大排列 n n n3 7n5 nlogn 2n 2 n3 log2n n1 2 log2n 3 2 n n n2 log2n 解答 log2n n1 2 log2n n nlog2n n2
  • c语言a b等于c的编程,简单的a+b (C语言代码)

    解题思路 题目中要求多次输入 所以需要一个死循环来进行控制 一般采用while 1 或者for 注意事项 scanf 函数需要加上取地址符 且它的返回值 它的返回值可以分成三种情况 1 正整数 表示正确输入参数的个数 例如执行 scanf
  • Java学习笔记——String类

    目录 API概述 案例 键盘录入字符串 String 概述 String类的常见构造方法 创建字符串对象的区别 String常见的面试题 字符串的比较 案例 用户登录 遍历字符串 案例 手机号屏蔽 字符串截取方法 案例 敏感词替换 字符串替
  • 决策树概述+模块介绍+重要参数(criterion+random_state&splitter+减枝参数+目标权重参数)+回归树(参数+实例+拟合正弦曲线)+泰坦尼克号生存者预测实例

    文章目录 什么是sklearn 一 决策树概述 一 概述 二 基础概念 三 决策树算法的核心是要解决两个问题 二 模块sklearn tree的使用 一 模块介绍 二 使用介绍 三 重要参数 一 criterion 二 random sta
  • JavaScript_day02

    文章目录 BOM与DOM操作 BOM操作 window子对象 history对象 location对象 掌握 弹出框 计时器相关 DOM操作 查找标签 节点操作 innerText 和 innerHTML 获取值操作 class css操作
  • 电机控制基础——定时器捕获单输入脉冲原理

    1 问题引出 在单片机与嵌入式开发中 某些场景需要捕获传感器的高电平 或低电平 信号的持续时间 如红外解码信号 编码器输入信号等 如下图 以单一的一段高电平输入信号为例 如何测量这段高电平的时间呢 从直观上理解 就是要不断的检测这个信号 当
  • IPv6与Volp

    文章目录 前言 1 IP v4与IP v6 1 1 IP v4的概念与存在的问题 1 2 ipv6概述 1 3 对比IP v4 IP v6的优点 1 3 ipv4与ipv6的包头比较 1 4 IP v6的基本术语 1 5 IP v6地址表示
  • 自主异常检测算法(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 Matlab代码 数据 4 参考文献 1 概述 文献来源 本文介绍了一种在实证数据分析
  • Java并发编程之CyclicBarrier详解

    简介 栅栏类似于闭锁 它能阻塞一组线程直到某个事件的发生 栅栏与闭锁的关键区别在于 所有的线程必须同时到达栅栏位置 才能继续执行 闭锁用于等待事件 而栅栏用于等待其他线程 CyclicBarrier可以使一定数量的线程反复地在栅栏位置处汇集
  • docker容器将系统盘空间占满的解决办法

    最近遇到一个问题 线上服务器的系统盘空间被占满了 导致服务不能正常运行了 docker启动时会报出下面这个错误 no space left on device 排查用到的命令 显示当前路径下占用空间超过1G的文件或文件夹 du h max
  • AD 原理图统一隐藏元器件的参数和序号

    AD 原理图统一隐藏元器件的参数和序号 如果隐藏元件参数 元件 右击 查找相似对象 确定 点击原理图 ctrl a 点击 属性对话框中 Part Conmment Hide 统一隐藏元件参数 如果隐藏元件序号 元件 右击 查找相似对象 确定
  • 用JAVA中的URL获取网页相关信息

    ava中有一个URL类 可以获取指定url的内容 import java io BufferedReader import java io InputStreamReader import java net URL public class
  • [Unity2D]在2D游戏里面实现人物的移动[消除抖动]

    Unity2D 在2D游戏里面实现人物的移动 先来一张效果图 一般的Unity2D游戏中 用WASD控制来移动人物角色的移动 缺陷 与含有碰撞器的强行碰撞时会发生抖动 原因 例如我人物要向左边走 利用脚本获取键盘输入 给人物角色一个向左边的
  • 一张图把DCDC电源拓扑“融会贯通”

    1 基本拓扑的由来 我们把一个电源电路抽象成一个黑盒电路模型 一个电源输入 一个电源输出 一个接地端口 对于非隔离电源 输入输出电路是共 地 的 所以非隔离电源的这个模型可以简化为图4 1 所示的模型 在所有的拓扑中 电感的一端需要连接到三
  • 使用docker部署golang编译环境

    前言 不想在windows上安装环境 打算docker部署 一拉一运行很方便 要注意的就是 官方的镜像跑起来后要改些参数再导成镜像 否则重启后改动消失 所以多一步 1 拉取镜像 运行镜像 docker pull golang docker
  • SpringBoot使用Swagger报NullPointerException

    第一次使用Swagger时报NullPointerException 在pom文件中引入Swagger 在启动项中加入注解 接口注解 运行出现NullPointerException 解决运行空指针问题 在pom文件中引入Swagger
  • Ini文件读取类,采用C++ STL实现

    背景 编程过程中经常会遇到读取Ini文件的场合 封装一个方便的类 能否避免重复编写 以后可复用 ini文件的格式很简单 并且不像xml之类的配置文件严谨 通常用于配置简单的键值对 本类测试文件如下