利用C++编写一个全功能的ini文件管理类

网络上有很多C++编写的ini文件管理类,但功能全面的很少。我自己编写了一个ini文件的管理类,包括以下几个实用功能:
1、 ini文件读取功能
2、 ini文件键值修改功能
3、 支持各种注释,包括独立的多行注释、单行注释和键值行后注释。
下面是一个ini文件的例子:

;这是一个ini文件的例子
[root]
host=127.0.0.1
port=8989

// 温度
[temp]
name=温湿度

# 低温告警值
# 这里是举一个例子
low=30    # 最低温度
high = 40   ; 最高温度


[db]
type=mysql
databaseName=smg 

具体的实现代码就是封装一个ini文件的类。
wsIni.h:

#include <string.h>

#ifndef SECTION_LEN
#define SECTION_LEN  30
#endif

#ifndef KEY_NAME_LEN
#define KEY_NAME_LEN  30
#endif

#ifndef KEY_VALUE_LEN
#define KEY_VALUE_LEN  100
#endif

#ifndef NOTE_LEN
#define NOTE_LEN  200
#endif

#ifndef SECTION_COMMENT_LEN
#define SECTION_COMMENT_LEN  1024
#endif

#ifndef ROW_COTENT_LEN
#define ROW_COTENT_LEN  1024
#endif

typedef struct KEY_VALUE
{
    char szKeyName[KEY_NAME_LEN];
    char szKeyValue[KEY_VALUE_LEN];
    char szNote[NOTE_LEN];   // 和key同行的尾部备注
    char *pszComment;   // key行的前导注释,内容可能较多,因此动态分配空间
    KEY_VALUE * pPre;
    KEY_VALUE * pNext;
}T_KEY_VALUE;

typedef struct SECTION
{
    char szSecName[SECTION_LEN];
    char *pszComment;   // 注释内容可能较多,因此动态分配空间
    SECTION * pPre;
    SECTION * pNext;
    KEY_VALUE * pKeyValue; 
}T_SECTION;

class wsIni
{
private:
public:
    wsIni();
    ~wsIni();

    int readIniFile(const char * pszFileName);
    int writeIniFile(const char * pszFileName);
    char * getKey(const char * pszSection, const char * pszKey);
    int setKey(const char * pszSection, const char * pszKey, const char * pszValue, const char * pszComment, const char * pszNote);
    void setSectionComment(const char * pszSection, const char * pszComment); 
    void printInfo();

private:
    char * killBadChar(char * pszCon);
    char * killValueComment(char *pszValue);

    T_SECTION * m_pFirstSection;
    T_SECTION * m_pCurSection;
    T_KEY_VALUE * m_pCurKeyvalue;
};

     在实现文件wsIni.cpp里,实现了头文件里的各个成员函数。其中最核心的就是读取ini文件的函数。

int wsIni::readIniFile(const char *pszFileName)
{
    FILE *pFile = fopen(pszFileName, "r");
    if (pFile == NULL)
    {
        printf("文件打开失败!");
        return -1;
    }

    fseek(pFile, 0, SEEK_END); // 先将指针偏移到文件尾
    long lLen = ftell(pFile);
    fseek(pFile, 0, SEEK_SET);
    char *pszCon = new char[lLen + 2];
    char *pszConSrc = pszCon;
    memset(pszCon, 0, lLen + 2);
    fread(pszCon, lLen, 1, pFile);
    strcat(pszCon, "\n"); // 防止有的文件最后一行不是以换行符结尾
    // printf(pszCon);
  
    const char *s = "\n";
    char *buf = strstr(pszCon, s); 
    char * pszCommentStart = pszCon;
    char szLine[ROW_COTENT_LEN] = ""; 
    while (buf != NULL)
    {              
        int len = buf - pszCon; 
        memset(szLine, 0, ROW_COTENT_LEN);  
        strncpy(szLine, pszCon, len);     
        killBadChar(szLine);
        if (strlen(szLine) > 0)
        { 
            if (szLine[0] == '[') // section
            {
                // 该位置之前的认为是当前section的注释
                int iComLen = pszCon - pszCommentStart;
                char * pszCom = new char[iComLen + 1];
                pszCom[iComLen] = '\0';
                strncpy(pszCom, pszCommentStart, iComLen);                

                T_SECTION * pCurSection = new T_SECTION();
                strncpy(pCurSection->szSecName, szLine + 1, strlen(szLine) - 2);
                printf("section:%s\n", pCurSection->szSecName);
                pCurSection->pNext = NULL;
                pCurSection->pKeyValue = NULL;
                pCurSection->pszComment = pszCom; 
                if (m_pFirstSection == NULL)
                {
                    m_pFirstSection = pCurSection;
                    m_pFirstSection->pPre = NULL;
                }
                else
                {
                    m_pCurSection->pNext = pCurSection;
                    pCurSection->pPre = m_pCurSection;
                }  
                m_pCurSection = pCurSection;       
                pszCommentStart = buf + 1;       
            }
            else if (szLine[0] == ';' || szLine[0] == '#' || (szLine[0] == '/' && szLine[1] == '/'))
            {
                printf("注释行\n");                         
            }
            else // key value
            {
                // 该位置之前的认为是当前key的注释
                int iComLen = pszCon - pszCommentStart;
                char * pszCom = new char[iComLen + 1];
                pszCom[iComLen] = '\0';
                strncpy(pszCom, pszCommentStart, iComLen);  

                T_KEY_VALUE *pKeyValue = new T_KEY_VALUE();
                char *pszEqualFlag = strchr(szLine, '=');
                strncpy(pKeyValue->szKeyName, szLine, pszEqualFlag - szLine);
                char *pszValue = pszEqualFlag + 1;
                pszValue = killBadChar(pszValue);

                pszValue = killValueComment(pszValue);
                strcpy(pKeyValue->szKeyValue, pszValue);
                pKeyValue->pszComment = pszCom;
                printf("key:%s value:%s\n", pKeyValue->szKeyName, pKeyValue->szKeyValue);

                pKeyValue->pPre = NULL;
                pKeyValue->pNext = NULL;
                if (m_pCurSection->pKeyValue == NULL) // 当前section下的第一个节点
                {
                    m_pCurSection->pKeyValue = pKeyValue;
                }
                else
                {
                    m_pCurKeyvalue->pNext = pKeyValue;
                    pKeyValue->pPre = m_pCurKeyvalue;
                }
                m_pCurKeyvalue = pKeyValue;
                pszCommentStart = buf + 1;
            }
        }
        pszCon = buf + strlen(s);      
        buf = strstr(pszCon, s); 
    }

    delete []pszConSrc;
    fclose(pFile);
    return 0;
}

 测试代码:
 

#include <stdio.h>
#include "wsIni.h"


int main()
{
    wsIni *obj = new wsIni();
    obj->readIniFile("./a.ini");
    obj->printInfo();

    char *pszValue = obj->getKey("temp", "name");
    printf("temp name:%s\n", pszValue);

    obj->setKey("temp", "low", "33.3", "", ";最低温度");
    obj->printInfo();

    obj->writeIniFile("./b.ini");
    delete obj;
    return 0;
}

       运行结果:

完整代码可以去这里下载:
http://kbase12.com/codedemo/doc/detail?id=c4046a4471cf41b7bdd63d049c1058bb

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wave12_mp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值