C/C++自定义读取ini、cfg配置文件

常见cfg、ini文件如下:

[config1]
setting=192.168.1.1
[config2]
setting=192.168.1.2
[config3]
setting=192.168.1.3

示例代码使用

// opt_ini.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include 
#include "cfg.h"

int main()
{
    cfg_load("config.cfg");
	cfg_print();
	cfg_set("config1","setting","192.168.101.78");
	cfg_save("config2.cfg");
	cfg_print();
	cfg_release();
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件

 示例代码运行结果:

C/C++自定义读取ini、cfg配置文件_第1张图片 C/C++自定义读取ini、cfg配置文件_第2张图片

附主要代码: 

static int cfg_parse_stream(CFG_reader reader, void* stream, CFG_handler handler,
    void* user)
{

    char line[CFG_MAX_LINE];
    size_t max_line = CFG_MAX_LINE;
    char section[MAX_SECTION] = "";
    char prev_name[MAX_NAME] = "";

    char* start;
    char* end;
    char* name;
    char* value;
    int lineno = 0;
    int error = 0;


#define HANDLER(u, s, n, v) handler(u, s, n, v)

    while (reader(line, (int)max_line, stream) != NULL) {


        lineno++;

        start = line;
        if (lineno == 1 && (unsigned char)start[0] == 0xEF &&
            (unsigned char)start[1] == 0xBB &&
            (unsigned char)start[2] == 0xBF) {
            start += 3;
        }
        start = lskip(rstrip(start));

        if (strchr(CFG_START_COMMENT_PREFIXES, *start)) {
            /* Start-of-line comment */
        }

        else if (*prev_name && *start && start > line) {

            end = find_chars_or_comment(start, NULL);
            if (*end)
                *end = '\0';
            rstrip(start);
            if (!HANDLER(user, section, prev_name, start) && !error)
                error = lineno;
        }

        else if (*start == '[') {
            /* A "[section]" line */
            end = find_chars_or_comment(start + 1, "]");
            if (*end == ']') {
                *end = '\0';
                strncpy0(section, start + 1, sizeof(section));
                *prev_name = '\0';
            }
            else if (!error) {
                /* No ']' found on section line */
                error = lineno;
            }
        }
        else if (*start) {
            /* Not a comment, must be a name[=:]value pair */
            end = find_chars_or_comment(start, "=:");
            if (*end == '=' || *end == ':') {
                *end = '\0';
                name = rstrip(start);
                value = end + 1;

                end = find_chars_or_comment(value, NULL);
                if (*end)
                    *end = '\0';
                value = lskip(value);
                rstrip(value);

                /* Valid name[=:]value pair found, call handler */
                strncpy0(prev_name, name, sizeof(prev_name));
                if (!HANDLER(user, section, name, value) && !error)
                    error = lineno;
            }
            else if (!error) {

                error = lineno;
            }
        }
    }

    return error;
}

static int cfg_parse_file(FILE* file, CFG_handler handler, void* user)
{
    return cfg_parse_stream((CFG_reader)fgets, file, handler, user);
}

static int cfg_parse(const char* filename, CFG_handler handler, void* user)
{
    FILE* file;
    int error;

    file = fopen(filename, "r");
    if (!file) {
        cfg_error("%s:%03d open %s error!\n", __FUNCTION__, __LINE__, filename);
        return -1;
    }
    error = cfg_parse_file(file, handler, user);
    fclose(file);
    return error;
}
int User;
static char Prev_section[50];

static unsigned int TrailerDateOfProduction(char* s)
{
    unsigned int ret;
    int i;

    ret = 0;
    if (!s)
    {
        return 0;
    }
    while (*s != '\0') {
        if (*s=='-')
            s++;
        if (*s >= '0' && *s <= '9')
            i = *s - '0';
        else if (*s >= 'a' && *s <= 'f')
            i = *s - 'a' + 0xa;
        else if (*s >= 'A' && *s <= 'F')
            i = *s - 'A' + 0xa;
        else
            return 0;
        ret = (ret << 4) + i;
        s++;
    }

    return ret;
}

/**
 * \description cfg init.
 * 
 * \author sunsz
 * \date   2023/09/23 
 * 
 */
static int GetConfig(void* user, const char* section, const char* name, const char* value){
    size_t len = 0;
    unsigned int cfg_num = 0;
    unsigned int cfg_data_num = 0;
    User = *((int*)user);
    if (!section) {
        return 1;
    }
    if (!name) {
        return 1;
    }
    if (!value) {
        cfg_error("%s:%03d [%s]%s = null\n", __FUNCTION__, __LINE__, section, name);
        return 1;
    }
    if (section && (!_stricmp(section, Prev_section))) {
        len = strlen(section);
        cfg_num = _cfg_config.cfg_section_num - 1;
        cfg_data_num = _cfg_config.cfg_section[cfg_num].cfg_data_num;
        _cfg_config.cfg_section[cfg_num].cfg_section_name = malloc(len + 1);
        if (_cfg_config.cfg_section[cfg_num].cfg_section_name != NULL) {
            memset(_cfg_config.cfg_section[cfg_num].cfg_section_name, 0, len + 1);
            strcpy(_cfg_config.cfg_section[cfg_num].cfg_section_name, section);
        }   

        len = strlen(name);
        _cfg_config.cfg_section[cfg_num].cfg_data[cfg_data_num].cfg_name = malloc(len + 1);
        if (_cfg_config.cfg_section[cfg_num].cfg_data[cfg_data_num].cfg_name != NULL) {
            memset(_cfg_config.cfg_section[cfg_num].cfg_data[cfg_data_num].cfg_name, 0, len + 1);
            strcpy(_cfg_config.cfg_section[cfg_num].cfg_data[cfg_data_num].cfg_name, name);
        }

        len = strlen(value);
        _cfg_config.cfg_section[cfg_num].cfg_data[cfg_data_num].cfg_value = malloc(len + 1);
        if (_cfg_config.cfg_section[cfg_num].cfg_data[cfg_data_num].cfg_value != NULL) {
            memset(_cfg_config.cfg_section[cfg_num].cfg_data[cfg_data_num].cfg_value, 0, len + 1);
            strcpy(_cfg_config.cfg_section[cfg_num].cfg_data[cfg_data_num].cfg_value, value);
        }
        _cfg_config.cfg_section[cfg_num].cfg_data_num++;
        strcpy(Prev_section, section);
        return 0;
    }else if (section) {
        cfg_num = _cfg_config.cfg_section_num;
        cfg_data_num = _cfg_config.cfg_section[cfg_num].cfg_data_num;
        len = strlen(section);
        _cfg_config.cfg_section[cfg_num].cfg_section_name = malloc(len + 1);
        if (_cfg_config.cfg_section[cfg_num].cfg_section_name != NULL) {
            memset(_cfg_config.cfg_section[cfg_num].cfg_section_name, 0, len + 1);
            strcpy(_cfg_config.cfg_section[cfg_num].cfg_section_name, section);
        }
        len = strlen(name);
        _cfg_config.cfg_section[cfg_num].cfg_data[cfg_data_num].cfg_name = malloc(len + 1);
        if (_cfg_config.cfg_section[cfg_num].cfg_data[cfg_data_num].cfg_name != NULL) {
            memset(_cfg_config.cfg_section[cfg_num].cfg_data[cfg_data_num].cfg_name, 0, len + 1);
            strcpy(_cfg_config.cfg_section[cfg_num].cfg_data[cfg_data_num].cfg_name, name);
        }
        len = strlen(value);
        _cfg_config.cfg_section[cfg_num].cfg_data[cfg_data_num].cfg_value = malloc(len + 1);
        if (_cfg_config.cfg_section[cfg_num].cfg_data[cfg_data_num].cfg_value != NULL) {
            memset(_cfg_config.cfg_section[cfg_num].cfg_data[cfg_data_num].cfg_value, 0, len + 1);
            strcpy(_cfg_config.cfg_section[cfg_num].cfg_data[cfg_data_num].cfg_value, value);
        }
        _cfg_config.cfg_section[cfg_num].cfg_data_num++;
        _cfg_config.cfg_section_num++;
        strcpy(Prev_section, section);
        return 0;
    }
    return 0;
}
/**
 * \description set cfg value.
 * 
 * \author sunsz
 * \date   2023/09/23 
 * 
 */
int cfg_set(const char*section, const char*name, const char*value) {
    int len = 0;
    int _sectionin = 0;
    unsigned int cfg_num = 0;
    unsigned int cfg_data_num = 0;
    cfg_debug("%s:%03d\n", __FUNCTION__, __LINE__);
    if (section == NULL || name == NULL || value == NULL) {
        cfg_error("%s:%03d parameter null!\n", __FUNCTION__, __LINE__);
        return 1;
    }
    for (size_t i = 0; i < _cfg_config.cfg_section_num; i++) {
        if (!_stricmp(_cfg_config.cfg_section[i].cfg_section_name, section)) {
            _sectionin = 1;
            for (size_t j = 0; j < _cfg_config.cfg_section[i].cfg_data_num; j++) {
                if (_cfg_config.cfg_section[i].cfg_data[j].cfg_name) {
                    if (!_stricmp(_cfg_config.cfg_section[i].cfg_data[j].cfg_name, name)) {
                        if (_cfg_config.cfg_section[i].cfg_data[j].cfg_value != NULL) {
                            len = strlen(_cfg_config.cfg_section[i].cfg_data[j].cfg_value);
                            memset(_cfg_config.cfg_section[i].cfg_data[j].cfg_value, 0, len);
                            free(_cfg_config.cfg_section[i].cfg_data[j].cfg_value);
                            _cfg_config.cfg_section[i].cfg_data[j].cfg_value = NULL;
                            if (value[0]) {
                                len = strlen(value);
                                _cfg_config.cfg_section[i].cfg_data[j].cfg_value = malloc(len + 1);
                                if (_cfg_config.cfg_section[i].cfg_data[j].cfg_value != NULL) {
                                    memset(_cfg_config.cfg_section[i].cfg_data[j].cfg_value, 0, len + 1);
                                    strcpy(_cfg_config.cfg_section[i].cfg_data[j].cfg_value, value);
                                }
                            }
                            else {
                                len = 1;
                                _cfg_config.cfg_section[i].cfg_data[j].cfg_value = malloc(len + 1);
                                if (_cfg_config.cfg_section[i].cfg_data[j].cfg_value != NULL) {
                                    memset(_cfg_config.cfg_section[i].cfg_data[j].cfg_value, 0, len + 1);
                                    strcpy(_cfg_config.cfg_section[i].cfg_data[j].cfg_value, "");
                                }
                            }
                        }
                        else {
                            if (value[0]) {
                                len = strlen(value);
                                _cfg_config.cfg_section[i].cfg_data[j].cfg_value = malloc(len + 1);
                                if (_cfg_config.cfg_section[i].cfg_data[j].cfg_value != NULL) {
                                    memset(_cfg_config.cfg_section[i].cfg_data[j].cfg_value, 0, len + 1);
                                    strcpy(_cfg_config.cfg_section[i].cfg_data[j].cfg_value, value);
                                }
                            }
                            else {
                                len = 1;
                                _cfg_config.cfg_section[i].cfg_data[j].cfg_value = malloc(len + 1);
                                if (_cfg_config.cfg_section[i].cfg_data[j].cfg_value != NULL) {
                                    memset(_cfg_config.cfg_section[i].cfg_data[j].cfg_value, 0, len + 1);
                                    strcpy(_cfg_config.cfg_section[i].cfg_data[j].cfg_value, "");
                                }
                            }
                        }
                        return 0;
                    }
                }
                   
            }

            //没有找到name
            if (name[0] && value[0]) {
                len = strlen(name);
                cfg_data_num = _cfg_config.cfg_section[i].cfg_data_num;
                _cfg_config.cfg_section[i].cfg_data[cfg_data_num].cfg_name = malloc(len + 1);
                if (_cfg_config.cfg_section[i].cfg_data[cfg_data_num].cfg_name != NULL) {
                    memset(_cfg_config.cfg_section[i].cfg_data[cfg_data_num].cfg_name, 0, len + 1);
                    strcpy(_cfg_config.cfg_section[i].cfg_data[cfg_data_num].cfg_name, name);
                }

                len = strlen(value);
               _cfg_config.cfg_section[i].cfg_data[cfg_data_num].cfg_value = malloc(len + 1);
                if (_cfg_config.cfg_section[i].cfg_data[cfg_data_num].cfg_value != NULL) {
                     memset(_cfg_config.cfg_section[i].cfg_data[cfg_data_num].cfg_value, 0, len + 1);
                     strcpy(_cfg_config.cfg_section[i].cfg_data[cfg_data_num].cfg_value, value);
                 }
               _cfg_config.cfg_section[i].cfg_data_num++;
               return 0;
            }
        } 
    }
    if (!_sectionin) {//没有找到section
        if (name[0] && value[0]) {
            len = strlen(section);
            cfg_num = _cfg_config.cfg_section_num;
            cfg_data_num = _cfg_config.cfg_section[cfg_num].cfg_data_num;
            _cfg_config.cfg_section[cfg_num].cfg_section_name = malloc(len + 1);
            if (_cfg_config.cfg_section[cfg_num].cfg_section_name != NULL) {
                memset(_cfg_config.cfg_section[cfg_num].cfg_section_name, 0, len + 1);
                strcpy(_cfg_config.cfg_section[cfg_num].cfg_section_name, section);
            }

            len = strlen(name);
            _cfg_config.cfg_section[cfg_num].cfg_data[cfg_data_num].cfg_name = malloc(len + 1);
            if (_cfg_config.cfg_section[cfg_num].cfg_data[cfg_data_num].cfg_name != NULL) {
                memset(_cfg_config.cfg_section[cfg_num].cfg_data[cfg_data_num].cfg_name, 0, len + 1);
                strcpy(_cfg_config.cfg_section[cfg_num].cfg_data[cfg_data_num].cfg_name, name);
            }

            len = strlen(value);
            _cfg_config.cfg_section[cfg_num].cfg_data[cfg_data_num].cfg_value = malloc(len + 1);
            if (_cfg_config.cfg_section[cfg_num].cfg_data[cfg_data_num].cfg_value != NULL) {
                memset(_cfg_config.cfg_section[cfg_num].cfg_data[cfg_data_num].cfg_value, 0, len + 1);
                strcpy(_cfg_config.cfg_section[cfg_num].cfg_data[cfg_data_num].cfg_value, value);
            }
            _cfg_config.cfg_section[cfg_num].cfg_data_num++;
            _cfg_config.cfg_section_num++;
            return 0;
        }
    }
    return 1;
}
/**
 * \description get value by section and name.
 * 
 * \author sunsz
 * \date   2023/09/23 
 * 
 */
char* cfg_get(const char* section, const char* name) {
    int len = 0;
    int _sectionin = 0;
    unsigned int cfg_num = 0;
    unsigned int cfg_data_num = 0;
    cfg_debug("%s:%03d\n", __FUNCTION__, __LINE__);
    if (section == NULL || name == NULL) {
        cfg_error("%s:%03d parameter null!\n", __FUNCTION__, __LINE__);
        return NULL;
    }
    for (size_t i = 0; i < _cfg_config.cfg_section_num; i++) {
        if (!_stricmp(_cfg_config.cfg_section[i].cfg_section_name, section)) {
            _sectionin = 1;
            for (size_t j = 0; j < _cfg_config.cfg_section[i].cfg_data_num; j++) {
                if (_cfg_config.cfg_section[i].cfg_data[j].cfg_name) {
                    if (!_stricmp(_cfg_config.cfg_section[i].cfg_data[j].cfg_name, name))
                        return _cfg_config.cfg_section[i].cfg_data[j].cfg_value;
                }

            }
        }
    }
    return NULL;
}
/**
 * \description write cfg data to log.
 * 
 * \author sunsz
 * \date   2023/09/23 
 * 
 */
void cfg_print() {
    cfg_debug("%s:%03d\n", __FUNCTION__, __LINE__);
    cfg_info("\n");
    for (size_t i = 0; i < _cfg_config.cfg_section_num; i++) {
        cfg_info("[%s]\n", _cfg_config.cfg_section[i].cfg_section_name);
        for (size_t j = 0; j < _cfg_config.cfg_section[i].cfg_data_num; j++) {
            cfg_info("%s=%s\n", _cfg_config.cfg_section[i].cfg_data[j].cfg_name, _cfg_config.cfg_section[i].cfg_data[j].cfg_value);
        }
    }
}
/**
 * \description write cfg data.
 * 
 * \author sunsz
 * \date   2023/09/23 
 * 
 */
int cfg_save(const char* cfg_name) {
    FILE* file;
    char buffer[1024] = { 0x00 };
    cfg_debug("%s:%03d\n", __FUNCTION__, __LINE__);
    file = fopen(cfg_name, "w");
    if (!file) {
        cfg_error("%s:%03d open %s error!\n",__FUNCTION__,__LINE__, cfg_name);
        return 1;
    }
    for (size_t i = 0; i < _cfg_config.cfg_section_num; i++) {
        memset(buffer, 0, 1024);
        sprintf(buffer, "[%s]\n", _cfg_config.cfg_section[i].cfg_section_name);
        fwrite(buffer,1,strlen(buffer), file);
        for (size_t j = 0; j < _cfg_config.cfg_section[i].cfg_data_num; j++) {
            sprintf(buffer, "%s=%s\n", _cfg_config.cfg_section[i].cfg_data[j].cfg_name, _cfg_config.cfg_section[i].cfg_data[j].cfg_value);
            fwrite(buffer, 1, strlen(buffer), file);
        }
    }
    fclose(file);
    return 0;
}
/**
 * \description release cfg memory.
 * 
 * \author sunsz
 * \date   2023/09/23 
 * 
 */
void cfg_release() {
    cfg_debug("%s:%03d\n", __FUNCTION__, __LINE__);
    for (size_t i = 0; i < _cfg_config.cfg_section_num; i++) {
        if (_cfg_config.cfg_section[i].cfg_section_name != NULL) {
            free(_cfg_config.cfg_section[i].cfg_section_name);
            _cfg_config.cfg_section[i].cfg_section_name = NULL;
        }
        for (size_t j = 0; j < _cfg_config.cfg_section[i].cfg_data_num; j++) {
            if (_cfg_config.cfg_section[i].cfg_data[j].cfg_name != NULL) {
                free(_cfg_config.cfg_section[i].cfg_data[j].cfg_name);
                _cfg_config.cfg_section[i].cfg_data[j].cfg_name = NULL;
            }
            if (_cfg_config.cfg_section[i].cfg_data[j].cfg_value != NULL) {
                free(_cfg_config.cfg_section[i].cfg_data[j].cfg_value);
                _cfg_config.cfg_section[i].cfg_data[j].cfg_value = NULL;
            }
        }
        _cfg_config.cfg_section[i].cfg_data_num = 0;
    }
    _cfg_config.cfg_section_num = 0;
}
/**
 * \description read cfg.
 * 
 * \author sunsz
 * \date   2023/09/23 
 * 
 */
int cfg_load(const char *cfg_name) {
    static int u = 100;
    int e;
    *Prev_section = '\0';
    cfg_debug("%s:%03d\n", __FUNCTION__, __LINE__);
    memset(&_cfg_config, 0, sizeof(CFG_CONFIG));
    _cfg_config.cfg_section_num = 0;
    e = cfg_parse(cfg_name, GetConfig, &u);
    u++;
    return e;
}

你可能感兴趣的:(c语言,c++)