ini_reader.c
/*
* brief: ini文件读取方法
* author: chengs
* date: 2024.05.13
*/
#include <glib.h>
#include "ini_reader.h"
#include "log.h"
#include "zstring.h"
/**
*
* 作用: 将psect 当section加入ini
* 参数: psect 为section的名字,pini_file为ini文件
*
* */
void AddSection(const pchar psect, GPtrArray_autoptr pini_file)
{
PINI_SECTION pini_section = malloc(sizeof(INI_SECTION));
memset(pini_section, 0, sizeof(INI_SECTION));
SetZString(psect, &pini_section->str_section);
g_ptr_array_add(pini_file, (gpointer) pini_section);
}
/**
*
* 作用: 将ini读入数组
* 参数: 需要读入的ini
*
* */
GPtrArray_autoptr read_ini_to_array(pchar file_name)
{
if (!file_name)
{
log_error(__FILE__, __LINE__, "file_name is null");
return NULL;
}
FILE *fp = NULL;
fp = fopen(file_name, "r");
if (fp == NULL)
{
log_error(__FILE__, __LINE__, "fp is null file_name: %s", file_name);
return NULL;
}
char sLine[INI_LINE_NUM]={0};
char sSect[INI_SECTION_LEN]={0};
char sKey[INI_KEY_LEN]={0};
char sValue[INI_VALUE_LEN]={0};
GPtrArray_autoptr pini_file = g_ptr_array_new();
while (fgets(sLine, INI_LINE_NUM, fp) != NULL)
{
memset(sValue, 0, INI_VALUE_LEN);
memset(sSect, 0, INI_SECTION_LEN);
// 去除末尾换行符
sLine[strcspn(sLine, "\n")] = '\0';
if (sLine[0]==';' || sLine[0]=='#' || sLine[0]=='\0' || sLine[0]==' ' || sLine[0]=='\r\n')
continue;
if (sLine[0]=='[')
{
sscanf(sLine, "[%[^]]", sSect);
AddSection(sSect, pini_file);
}
else
{
sscanf(sLine, "%[^=]=%[^\r\n]", sKey, sValue);
if (pini_file->len == 0)
AddSection(DFT_INI_SECTION, pini_file);
PINI_SECTION pini_section = (PINI_SECTION)g_ptr_array_index(pini_file, pini_file->len - 1);
if (pini_section->pchild_kv == NULL)
pini_section->pchild_kv = g_ptr_array_new();
PINI_CHILD pini_child = malloc(sizeof(INI_CHILD));
g_ptr_array_add(pini_section->pchild_kv, (gpointer) pini_child);
SetZString(sKey, &pini_child->str_key);
SetZString(sValue, &pini_child->str_value);
// TODO: 保存参数
}
}
fclose(fp);
return pini_file;
}
/**
*
* 作用: 从ini文件中查找某个section下,是否存在某个key
* 参数: str_key ,key值
*
* */
bool find_ini_key(GPtrArray_autoptr pini_file, const char* str_section, const char* str_key)
{
if (NULL == pini_file || NULL == str_section || NULL == str_key)
{
log_error(__FILE__, __LINE__, "NULL == pini_file || NULL == str_section || NULL == str_key ;\
pini_file = %p, str_section = %p, str_key = %p", pini_file, str_section, str_key);
return false;
}
bool bfind = false;
for (int i = 0; i < pini_file->len; i++)
{
if (bfind)
{
log_info(__FILE__, __LINE__, " bfind is true");
break;
}
PINI_SECTION pini_section = (PINI_SECTION)g_ptr_array_index(pini_file, i);
log_info(__FILE__, __LINE__, "section: %s", pini_section->str_section.value);
if (strcmp(pini_section->str_section.value , str_section) != 0)
continue;
for (size_t i = 0; i < pini_section->pchild_kv->len; i++)
{
PINI_CHILD pini_child = (PINI_CHILD)g_ptr_array_index(pini_section->pchild_kv, i);
log_info(__FILE__, __LINE__, "key: %s", pini_child->str_key.value);
log_info(__FILE__, __LINE__, "value: %s", pini_child->str_value.value);
if(strcmp(pini_child->str_key.value, str_key) == 0)
{
bfind = true;
break;
}
}
}
return bfind;
}
/**
*
* 作用: pini_file的内存释放
* 参数: 需要释放的ini
*
* */
void release_ini(const GPtrArray_autoptr pini_file)
{
for (int i = 0; i < pini_file->len; i++)
{
PINI_SECTION pini_section = (PINI_SECTION)g_ptr_array_index(pini_file, i);
log_info(__FILE__, __LINE__, "section: %s", pini_section->str_section);
for (size_t i = 0; i < pini_section->pchild_kv->len; i++)
{
PINI_CHILD pini_child = (PINI_CHILD)g_ptr_array_index(pini_section->pchild_kv, i);
log_info(__FILE__, __LINE__, "release key: %s", pini_child->str_key.value);
log_info(__FILE__, __LINE__, "release value: %s", pini_child->str_value.value);
free(pini_child->str_key.value);
free(pini_child->str_value.value);
}
free(pini_section->str_section.value);
}
g_ptr_array_free(pini_file, true);
}
/**
*
* 作用: 将文件按行读入数组
* 参数: 需要读的文件名
*
* */
GPtrArray_autoptr read_line_to_array(pchar file_name)
{
if (!file_name)
{
log_error(__FILE__, __LINE__, "file_name is null");
return NULL;
}
FILE *fp = NULL;
fp = fopen(file_name, "r");
if (fp == NULL)
{
log_error(__FILE__, __LINE__, "fp is null file_name: %s", file_name);
return NULL;
}
char sLine[INI_LINE_NUM]={0};
GPtrArray_autoptr pfile = g_ptr_array_new();
while (fgets(sLine, INI_LINE_NUM, fp) != NULL)
{
// 去除末尾换行符
size_t pos = strcspn(sLine, "\n");
if(pos >= 0 && pos < strlen(sLine))
sLine[pos] = '\0';
// 去除末尾/r
pos = strcspn(sLine, "\r");
if(pos >= 0 && pos < strlen(sLine))
sLine[pos] = '\0';
if (strcmp("",sLine) == 0)
continue; //排除空行
PZSTRING pzstring = malloc(sizeof(ZSTRING));
SetZString(sLine, pzstring);
g_ptr_array_add(pfile, (gpointer) pzstring);
}
fclose(fp);
return pfile;
}
void release_line_array(GPtrArray_autoptr line_array)
{
if (!line_array)
return;
for (size_t i = 0; i < line_array->len; i++)
{
char temp[MAX_PATH] = {0};
PZSTRING pfile = (PZSTRING)g_ptr_array_index(line_array, i);
free(pfile->value);
}
g_ptr_array_free(line_array, true);
}
ini_reader.h
#ifndef _INI_READER_H_
#define _INI_READER_H_
#include "ztype.h"
#define DFT_INI_SECTION "default_0"
#define INI_LINE_NUM 512
#define INI_SECTION_LEN 64
#define INI_KEY_LEN 128
#define INI_VALUE_LEN 128
typedef struct INI_CHILD_STRU
{
ZSTRING str_key;
ZSTRING str_value;
}INI_CHILD,*PINI_CHILD;
typedef struct INI_SECTION_STRU
{
ZSTRING str_section;
GPtrArray_autoptr pchild_kv;
}INI_SECTION,*PINI_SECTION;
/**
*
* 作用: 将psect 当section加入ini
* 参数: psect 为section的名字,pini_file为ini文件
*
* */
void AddSection(const pchar psect, GPtrArray_autoptr pini_file);
/**
*
* 作用: 将ini读入数组
* 参数: 需要读入的ini
*
* */
GPtrArray_autoptr read_ini_to_array(pchar file_name);
/**
*
* 作用: 从ini文件中查找某个section下,是否存在某个key
* 参数: str_key ,key值
*
* */
bool find_ini_key(GPtrArray_autoptr pini_file, const char* str_section, const char* str_key);
/**
*
* 作用: pini_file的内存释放
* 参数: 需要释放的ini
*
* */
void release_ini(const GPtrArray_autoptr pini_file);
/**
*
* 作用: 将文件按行读入数组
* 参数: 需要读的文件名
*
* */
GPtrArray_autoptr read_line_to_array(pchar file_name);
#endif
代码中使用了glib库作为数据结构,如果使用其他的,请自行替换。