本例子根据给定的 ini 文件名和给定的 ini 节点获取对应节点的信息, 并保存在 _ini_struct 结构体数组中。
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <string.h>
-
#include <ctype.h>
-
-
#ifndef SUCCESS
-
#define SUCCESS 1
-
#endif
-
-
typedef struct _ini_struct { /* 以 key , value 方式,保存 ini 节点中的节点信息 */
-
char *key;
-
char *value;
-
} INISTRUST ;
-
-
-
/* TRIM LEFT */
-
-
int rtrim( char *pszString)
-
{
-
int nForwardCursor = 0;
-
int nTrailingCursor = 0;
-
int bTrim = 1;
-
-
for( nForwardCursor = 0 ; pszString[nForwardCursor] != '\0'; nForwardCursor++ )
-
if ( bTrim && isspace( pszString[nForwardCursor] ))
-
continue ;
-
else {
-
bTrim = 0;
-
pszString[nTrailingCursor] = pszString[nForwardCursor];
-
nTrailingCursor++;
-
}
-
pszString[nTrailingCursor] = '\0';
-
return SUCCESS;
-
}
-
-
/* TRIM RIGHT */
-
int ltrim( char *pszString )
-
{
-
int nForwardCursor = 0;
-
int nTrailingCursor = 0;
-
int bTrim = 1;
-
for ( nForwardCursor=strlen(pszString)-1;
-
nForwardCursor >= 0 && isspace( pszString[nForwardCursor] );
-
nForwardCursor-- )
-
{
-
}
-
pszString[nForwardCursor+1] = '\0';
-
return SUCCESS;
-
}
-
-
/* TRIM LEFT & RIGHT */
-
int trim(char *str)
-
{
-
ltrim(str);
-
rtrim(str);
-
return SUCCESS;
-
}
-
-
/* ********************************************************
-
* char **read_ini(char *filename , int *iniline )
-
* 从文件名为 filename 的 ini 文件中读取信息,并将其
-
* 保存在一个 char *[] 字符串数组中。
-
* 传入参数:
-
* char *filename 一个有效的 ini 文件名
-
* int *iniline 该文件中读取的记录行数
-
* 返回值:
-
* char *[] 保存该 ini 文件的所有记录的
-
* 字符串数组
-
* ******************************************************* */
-
char **read_ini(char *filename,int *iniline)
-
{
-
FILE *fp;
-
char *str;
-
static char **ini_str;
-
int ini_i;
-
int i,j;
-
-
ini_str = ( char **)malloc(sizeof(char *));
-
*ini_str = ( char *)malloc(sizeof(char *)*1024);
-
str = ( char *)malloc(sizeof(char)*1024);
-
-
if ( (fp = fopen(filename,"rb")) != NULL )
-
{
-
ini_i = 0;
-
while(!feof(fp))
-
{
-
bzero(str,1024);
-
if ( fgets(str,1024,fp) != NULL )
-
{
-
for ( i = 0 ; i < strlen(str); i++ )
-
{
-
/* 切掉 ini 文件中的注释信息 */
-
if ( str[i] == ';' || str[i] == '\n' )
-
{
-
str[i] = '\0';
-
}
-
}
-
trim(str);
-
if ( str[0] != '\0' && str[0] != '\n') {
-
ini_str[ini_i] = ( char *)malloc(sizeof(char)*1024);
-
snprintf(ini_str[ini_i],1024,"%s",str);
-
ini_i++;
-
}
-
}
-
}
-
}
-
fclose(fp);
-
*iniline = ini_i;
-
return (char **)ini_str;
-
}
-
-
-
/* *********************************************************************************
-
* INISTRUST *get_ini_node ( char *filename , char *nodename,
-
* INISTRUST *_sec_node , int *node_size )
-
* 根据给定的ini文件名和指定的节点 ,提取该文件中指定节点的信息内
-
* 容,并将其保存在结构体 _ini_struct 数组中
-
* 传入参数:
-
* char *filename 一个有效的 ini 文件的文件名
-
* char *nodename 待提取的 ini 文件中的节点名
-
* INISTRUST *_sec_node 保存提取到的节点信息的 key,value 结构体数组
-
* int *node_size 保存该节点的信息记录条数,一个 key、value 对
-
* 为一条记录
-
* 返回值:
-
* struct *_ini_struct 保存提取的节点的 key、value 键值信息结构数组
-
* ******************************************************************************* */
-
INISTRUST *get_ini_node ( char *filename , char *nodename, INISTRUST *_sec_node , int *node_size )
-
{
-
INISTRUST *_ini_node;
-
char **ini_array;
-
int ini_line;
-
int i,j,flag = 0;
-
char *token;
-
int i_size = 0;
-
-
*node_size = 0;
-
_ini_node = _sec_node ;
-
-
_ini_node = (INISTRUST *)malloc(sizeof(INISTRUST));
-
_ini_node->key = (char *)malloc(sizeof(char)*128);
-
_ini_node->value = (char *)malloc(sizeof(char)*256);
-
ini_array = read_ini(filename,&ini_line);
-
for ( i = 0 ; i< ini_line ; i++ )
-
{
-
if ( ini_array[i][0] == '[' )
-
{
-
if ( strcmp(ini_array[i],nodename)) {
-
flag = 0;
-
continue;
-
} else {
-
flag = 1;
-
continue;
-
}
-
} else if ( flag == 1 ) {
-
_ini_node[i_size].key = (char *)malloc(sizeof(char)*128);
-
_ini_node[i_size].value = (char *)malloc(sizeof(char)*256);
-
token = strtok(ini_array[i],"=");
-
while( token != NULL )
-
{
-
if ( j %2 == 0 )
-
{
-
snprintf(_ini_node[i_size].key,128,"%s",token);
-
trim(_ini_node[i_size].key);
-
} else {
-
snprintf(_ini_node[i_size].value,256,"%s",token);
-
trim(_ini_node[i_size].value);
-
}
-
token=strtok(NULL,"=");
-
j++;
-
}
-
i_size++;
-
}
-
}
-
*node_size=i_size;
-
return (INISTRUST *)_ini_node;
-
}
-
-
-
int main ( int argc , char **argv)
-
{
-
char **ini_s;
-
int ini_line;
-
int i;
-
INISTRUST *s_ininode = get_ini_node ( argv[1] , argv[2], s_ininode , &ini_line );
-
printf("=== %d \n",ini_line);
-
for ( i = 0 ; i < ini_line ; i++ )
-
{
-
printf(" == KEY = %s \n",s_ininode[i].key);
-
printf(" == VOL = %s \n",s_ininode[i].value);
-
}
-
-
return 0;
-
}
以上是一个完整的从 ini 文件中提取指定节点信息的示例,可以直接使用。
基本实现思路是:
第一步:首先将 ini 文件读取出来,保存在 char *ini_array[] 字符串数组中,在保存的过程中,剔除了注释信息(ini文件中以 ';' 标注注释信息 ),并将每行信息的前后空格剔除。
第二步:将 char *ini_array[] 字符串数组传入 INISTRUCT *_get_ini_node 函数。
第三步:在_get_ini_node 函数中,首先判断每行的首字符是否是 '[' ,如果是,则该行是一个节点名,否则是某个节点下的 key、value, 当找到一个节点名时,对该节点字符串与传入的节点名称进行匹配,如果匹配成功,则将 flag = 1 ,表示下面的行是该节点的 key、value 值,对下面的行使用 strtok 进行拆解,拆解的匹配字符是“=”。然后将拆解的字符串分别存储到 _ini_node[i_size].key 和 _ini_node[i_size].value 中,然后返回到 for 循环中进行下一个判断。
注意事项:
1、此列子中应仔细体会字符串数组 char **ini_str 和结构体 struct _ini_struct *_ini_node 指针的使用方法,尤其是在 get_ini_node 函数中对结构体 struct _ini_struct *_ini_node 指针的两次内存分配操作。
2、本例子中使用了一个小技巧,即在函数 get_ini_node 定义了一个结构体指针 struct _ini_struct *_ini_node , 并将该指针直接指向了传入的结构体指针 struct _ini_struct *_sec_node , 从而实现了直接对 *_sec_node 的操作,实际上,程序没有返回 struct _ini_struct * 时,该程序也可以正常运行,并得到正确的结构,即在 main()函数中,作如下修改:
INISTRUCT *s_ininode = get_ini_node ( argv[1] , argv[2] , s_ininode , &iniline);
修改为:
INISTRUCT *s_ininode;
get_ini_node ( argv[1] , argv[2] , s_ininode , &iniline);
程序也可以正常运行,并得到正确的结果。
3、iniline 保存的是该节点的 key、value 的记录条数。
阅读(992) | 评论(0) | 转发(0) |