常见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 文件
示例代码运行结果:
附主要代码:
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;
}