c语言读取/保存配置文件 - 中秋贺礼
时间:2014年09月08日 人气:...

中秋,月圆人团圆,远离家乡亲人,唯有计算机自娱,特编写一套c语言版的读取配置文件接口,以方便使用。。。

在windows下使用gcc编译好使,linux下理论也应该是好用的。

------------------------conf.h------------------------------

#ifndef __CONF_H__
#define __CONF_H__

/* 文件大小,单位: 字节 */
#define FILE_SIZE_MAX  512

/* 定义每一行的最大长度,单位: 字节 */
#define LINE_LEN_MAX   32

/* ==============读取函数=============== */

/* 从配置文件中读取浮点型数据,成功返回ERROR_SUCCESS,失败返回ERROR_FAILED */
int conf_get_key_4double(IN const char *pcFile, IN const char *pcAppName, IN const char* pcKeyName, OUT double *pdKeyValue);

/* 从配置文件中读取整型数据,成功返回ERROR_SUCCESS,失败返回ERROR_FAILED */
int conf_get_key_4int(IN const char *pcFile, IN const char *pcAppName, IN const char* pcKeyName, OUT int *piKeyValue);

/* 从配置文件中读取长整型数据,成功返回ERROR_SUCCESS,失败返回ERROR_FAILED */
int conf_get_key_4long(IN const char *pcFile, IN const char *pcAppName, IN const char* pcKeyName, OUT long *plKeyValue);

/* 从配置文件中读取字符串型数据,成功返回ERROR_SUCCESS,失败返回ERROR_FAILED */
int conf_get_key_4str(IN const char *pcFile, IN const char *pcAppName, IN const char* pcKeyName, OUT char *pcKeyValue);


/* ==============保存函数=============== */

/* 将字符串数据存入配置文件,成功返回ERROR_SUCCESS,失败返回ERROR_FAILED */
int conf_set_key_4str(IN const char *pcFile, IN const char *pcAppName, IN const char* pcKeyName, IN const char *pcKeyValue);

/* 将整型数据存入配置文件,成功返回ERROR_SUCCESS,失败返回ERROR_FAILED */
int conf_set_key_4int(IN const char *pcFile, IN const char *pcAppName, IN const char* pcKeyName, IN const int iKeyValue);

/* 将长整型数据存入配置文件,成功返回ERROR_SUCCESS,失败返回ERROR_FAILED */
int conf_set_key_4long(IN const char *pcFile, IN const char *pcAppName, IN const char* pcKeyName, IN const long lKeyValue);

/* 将浮点型数据存入配置文件,成功返回ERROR_SUCCESS,失败返回ERROR_FAILED */
int conf_set_key_4double(IN const char *pcFile, IN const char *pcAppName, IN const char* pcKeyName, IN const double dKeyValue);

#endif /* __CONF_H__ */


-----------------------------conf.c----------------------------------------------


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "include/basetype.h"
#include "conf.h"

/* 查找状态 */
#define FLAG_START     0
#define FLAG_APP       1
#define FLAG_KEY       2
#define FLAG_NOTHING   3

/* 从配置文件中读取字符串型数据,成功返回ERROR_SUCCESS,失败返回ERROR_FAILED */
int conf_get_key_4str(IN const char *pcFile, IN const char *pcAppName, IN const char* pcKeyName, OUT char *pcKeyValue)
{
    int   iRet    = ERROR_FAILED;
    char *pcPos   = NULL;
    FILE *pstFile = NULL;
    char  szAppName[LINE_LEN_MAX];
    char  szKeyName[LINE_LEN_MAX];
    char  szKeyValue[LINE_LEN_MAX];
    char  acBuf[LINE_LEN_MAX];
    unsigned char ucFlag = FLAG_START;

    /* 打开配置文件 */
    pstFile = fopen(pcFile, "r");
    if (NULL == pstFile)
    {
        return ERROR_FAILED;
    }

    /* 移至文件头 */
    rewind(pstFile);

    /* 拼接查找的类型名称 */
    szAppName[0] = '�';
    sprintf(szAppName, "[%s]", pcAppName);

    /* 逐行从文件中读取 */
    while(NULL != fgets(acBuf, LINE_LEN_MAX, pstFile))
    {
        /* 先查找appname */
        if (FLAG_START == ucFlag)
        {
            if (0 == strncmp(szAppName, acBuf, strlen(szAppName)))
            {
                ucFlag = FLAG_APP;
                continue;
            }
        }

        /* 再查找keyname */
        if (FLAG_APP == ucFlag)
        {
            /* 忽略注视 */
            if ('#' == acBuf[0])
            {
                continue;
            }
            /* 在下一个appname之前没有找到keyname,则说明key不存在 */
            else if ('[' == acBuf[0])
            {
                break;
            }
            else
            {
                /* 以=为线索解析每条配置 */
                pcPos = strchr(acBuf, '=');
                if (NULL != pcPos)
                {
                    szKeyName[0] = '�';
                    szKeyValue[0] = '�';

                    /* 分离keyname,遇到=结束 */
                    sscanf(acBuf, "%[^=]", szKeyName);
                    if (0 == strncmp(pcKeyName, szKeyName, strlen(pcKeyName)))
                    {
                        /* 此时已找到keyname,分离keyvalue,遇到换行结束 */
                        sscanf(pcPos + 1, "%[^]", szKeyValue);
                        strcpy(pcKeyValue, szKeyValue);
                        ucFlag = FLAG_KEY;
                        break;
                    }
                }
            }
        }
    }

    /* 关闭配置文件 */
    fclose(pstFile);

    /* 只有成功找到keyname和keyvalue才算成功 */
    if (FLAG_KEY == ucFlag)
    {
        iRet = ERROR_SUCCESS;
    }

    return iRet;
}

/* 从配置文件中读取整型数据,成功返回ERROR_SUCCESS,失败返回ERROR_FAILED */
int conf_get_key_4int(IN const char *pcFile, IN const char *pcAppName, IN const char* pcKeyName, OUT int *piKeyValue)
{
    int iRet = ERROR_FAILED;
    char szKeyValue[LINE_LEN_MAX];

    szKeyValue[0] = '�';
    iRet = conf_get_key_4str(pcFile, pcAppName, pcKeyName, szKeyValue);
    if (ERROR_SUCCESS == iRet)
    {
        /* 将字符串转换为整型 */
        *piKeyValue = atoi(szKeyValue);
    }

    return iRet;
}

/* 从配置文件中读取长整型数据,成功返回ERROR_SUCCESS,失败返回ERROR_FAILED */
int conf_get_key_4long(IN const char *pcFile, IN const char *pcAppName, IN const char* pcKeyName, OUT long *plKeyValue)
{
    int iRet = ERROR_FAILED;
    char szKeyValue[LINE_LEN_MAX];

    szKeyValue[0] = '�';
    iRet = conf_get_key_4str(pcFile, pcAppName, pcKeyName, szKeyValue);
    if (ERROR_SUCCESS == iRet)
    {
        /* 将字符串转换为长整型 */
        *plKeyValue = atol(szKeyValue);
    }

    return iRet;
}

/* 从配置文件中读取浮点型数据,成功返回ERROR_SUCCESS,失败返回ERROR_FAILED */
int conf_get_key_4double(IN const char *pcFile, IN const char *pcAppName, IN const char* pcKeyName, OUT double *pdKeyValue)
{
    int iRet = ERROR_FAILED;
    char szKeyValue[LINE_LEN_MAX];

    szKeyValue[0] = '�';
    iRet = conf_get_key_4str(pcFile, pcAppName, pcKeyName, szKeyValue);
    if (ERROR_SUCCESS == iRet)
    {
        /* 将字符串转换为浮点型 */
        *pdKeyValue = atof(szKeyValue);
    }

    return iRet;
}

/* 将字符串数据存入配置文件,成功返回ERROR_SUCCESS,失败返回ERROR_FAILED */
int conf_set_key_4str(IN const char *pcFile, IN const char *pcAppName, IN const char* pcKeyName, IN const char *pcKeyValue)
{
    int   iRet    = ERROR_FAILED;
    char *pcPos   = NULL;
    FILE *pstFile = NULL;
    char  szAppName[LINE_LEN_MAX];
    char  szKeyName[LINE_LEN_MAX];
    char  szKeyValue[LINE_LEN_MAX];
    char  acBuf[LINE_LEN_MAX];
    char  acTotalFileBuf[FILE_SIZE_MAX];
    unsigned char ucFlag = FLAG_START;

    /* 打开配置文件 */
    pstFile = fopen(pcFile, "r");
    if (NULL == pstFile)
    {
        return ERROR_FAILED;
    }

    /* 移至文件头 */
    rewind(pstFile);

    /* 拼接查找的类型名称 */
    szAppName[0] = '�';
    sprintf(szAppName, "[%s]", pcAppName);

    /* 逐行从文件中读取 */
    while(NULL != fgets(acBuf, LINE_LEN_MAX, pstFile))
    {
        /* 先查找appname,再查找keyname */
        if(FLAG_START== ucFlag)
        {
            strcat(acTotalFileBuf, acBuf);

            /* 检查是否是appname */
            if (0 == strncmp(szAppName, acBuf, strlen(szAppName)))
            {
                ucFlag = FLAG_APP;
                continue;
            }
        }
        else
        {
            /* appname不存在此keyname则查找失败 */
            if (('[' == acBuf[0]) && (FLAG_KEY != ucFlag))
            {
                break;
            }
            else
            {
                /* 以=为线索解析每条配置 */
                pcPos = strchr(acBuf, '=');
                if (NULL != pcPos)
                {
                    szKeyName[0] = '�';
                    szKeyValue[0] = '�';

                    /* 分离keyname,遇到=结束 */
                    sscanf(acBuf, "%[^=]", szKeyName);
                    if (0 == strncmp(pcKeyName, szKeyName, strlen(pcKeyName)))
                    {
                        /* 此时已找到keyname,分离keyvalue,遇到换行结束 */
                        sscanf(pcPos + 1, "%[^]", szKeyValue);

                        /* 如果keyvalue与原来相同则无需继续操作 */
                        if (0 == strcmp(szKeyValue, pcKeyValue))
                        {
                            ucFlag = FLAG_NOTHING;
                            break;
                        }
                        else
                        {
                            acBuf[0] = '�';
                            /* 拼装新数据,末尾要加换行符 */
                            sprintf(acBuf, "%s=%s", szKeyName, pcKeyValue);
                            strcat(acTotalFileBuf, acBuf);
                            ucFlag = FLAG_KEY;
                            continue;
                        }
                    }
                }

                /* 新的appname/不匹配的keyname,则追加到缓冲区 */
                strcat(acTotalFileBuf, acBuf);
            }
        }
    }

    /* 关闭配置文件 */
    fclose(pstFile);

    if (FLAG_KEY == ucFlag)
    {
        /* 先删除配置文件,再创建保存一份新的 */
        remove(pcFile);

        pstFile = fopen(pcFile, "w+");
        if (NULL == pstFile)
        {
            return ERROR_FAILED;
        }
        fputs(acTotalFileBuf, pstFile);
        fclose(pstFile);

        iRet = ERROR_SUCCESS;
    }
    else if(FLAG_NOTHING == ucFlag)
    {
        iRet = ERROR_SUCCESS;
    }

    return iRet;
}

/* 将整型数据存入配置文件,成功返回ERROR_SUCCESS,失败返回ERROR_FAILED */
int conf_set_key_4int(IN const char *pcFile, IN const char *pcAppName, IN const char* pcKeyName, IN const int iKeyValue)
{
    int iRet = ERROR_FAILED;
    char szKeyValue[LINE_LEN_MAX];

    szKeyValue[0] = '�';
    sprintf(szKeyValue, "%d", iKeyValue);

    iRet = conf_set_key_4str(pcFile, pcAppName, pcKeyName, szKeyValue);

    return iRet;
}

/* 将长整型数据存入配置文件,成功返回ERROR_SUCCESS,失败返回ERROR_FAILED */
int conf_set_key_4long(IN const char *pcFile, IN const char *pcAppName, IN const char* pcKeyName, IN const long lKeyValue)
{
    int iRet = ERROR_FAILED;
    char szKeyValue[LINE_LEN_MAX];

    szKeyValue[0] = '�';
    sprintf(szKeyValue, "%ld", lKeyValue);

    iRet = conf_set_key_4str(pcFile, pcAppName, pcKeyName, szKeyValue);

    return iRet;
}

/* 将浮点型数据存入配置文件,成功返回ERROR_SUCCESS,失败返回ERROR_FAILED */
int conf_set_key_4double(IN const char *pcFile, IN const char *pcAppName, IN const char* pcKeyName, IN const double dKeyValue)
{
    int iRet = ERROR_FAILED;
    char szKeyValue[LINE_LEN_MAX];

    szKeyValue[0] = '�';
    sprintf(szKeyValue, "%g", dKeyValue);

    iRet = conf_set_key_4str(pcFile, pcAppName, pcKeyName, szKeyValue);

    return iRet;
}


---------------------test.c-----------------------------------

#include <stdio.h>

#include "include/basetype.h"
#include "conf.h"

int main(IN int argc, IN char** argv)
{
    int  iRet = ERROR_FAILED;
    char szName[LINE_LEN_MAX];

    IGNOPARA(argc);
    IGNOPARA(argv);

    szName[0] = '�';
    iRet = conf_get_key_4str("x.conf", "cfg", "name", szName);
    if (ERROR_SUCCESS == iRet)
    {
        printf("get success.");
        printf("name: %s.", szName);
    }
    else
    {
        printf("get failed.");
    }

    iRet = conf_set_key_4double("x.conf", "run", "width", 456.986);
    if (ERROR_SUCCESS == iRet)
    {
        printf("set success.");
    }
    else
    {
        printf("set failed.");
    }

    return ERROR_SUCCESS;
}


-----------------------x.conf--------------------------------


[cfg]
name=peter
age=20
sex=1

[run]
#这是注释
height=158
width=874


最后,就省略最后的截图吧~~~ 


最美丽江花花草草大美长白山西北环形古都长安
热门评论