如何实现从配置文件到内存数据结构的映射
1. 先把文件内容读到内存中
while( fgets(fgets_buf,sizeof(fgets_buff)-1,fp))
2. 对每一行进行处理
当碰到“#”就跳过这一行,if(fgets_buff[0]=="#") continue;
去掉每一行前面的空格,或者TAB
如何判断:static int is_ws(char * const ptr)
{
return (*ptr==' '||*ptr=='\r'||*ptr=='\t'||*ptr=='\n')?1:0;
}
删除其空格等字符: char * eat_ws(char* ptr,size_t * const len)
{
if(!ptr||!*len)
return NULL;
while(*len&&is_ws(ptr))
++ptr,--(*len);
return *len?ptr:NULL;
}
3. 根据配置文件的格式 TAG=VALUE
因此可以通过“=”把这个记录中的TAG和VALUE分开
equal=strchr(str_buff,'=');
equal='\0';
因此TAG=str_buf, VALUE=equal+1;
4. 构造一个映射表 格式如下: TAG->fparse
typedef int (*fparser)(batch_context * const bctx,char * const value)
typedef struct tag_parser_pair
{
char *tag;
fparser parser;
} tag_parser_pair 建立一个能将解析函数和标记关联起来的数据结构
static const tag_parser_pair tp_map[]
{
{"batch_name", batch_name_parser},
{"client_num_max",client_num_max_parser},
……
} 建立一个map 表,把所有的TAG和fparser都罗列出来。
5. 找到对应str_buff的解析函数fpaser
for(index=0;tp_map[index].tag;index++)
{
if(!strcmp(tp_map[index].tag,tag))
return tp_map[index].parser;
}
6. 调用对应的解析函数fparser把VALUE写入到结构batch_context中对应的项中
(*parser)(&bctx_array[*batch_num],value)
不同的parser完成不同的功能,但是其接口是一样的,比如batch_name_parser就是把value写入到batch_context结构中的batch_name中
static int batch_name_parser(batch_context * const bctx, char* const value)
{
strncpy(bctx->batch_name,value,batch_name_size);
}
7. fclose(fp) 关闭该文件描述符