1 libconfig是什么?
Libconfig是一个结构化的配置文件库,它可以定义一些配置文件,例如test.cfg . 它比xml可读性更好,而且更简洁。而且不像xml,它是 type-aware类型自我感知的,因此不需要做string parsing (分词?). 而ini太弱。
2 配置文件说明
libconfig支持结构化、层次化的配置。这些配置可以从文件中读取或写入文件,也可以在内存中操作。一个配置由一组setting构成,setting由名字(name)关联,并有相应的值(value)。一个值(value)可以是以下任意一种类型:
标量值(scalarvalue):整型、64位整型、浮点数、布尔值或者字符串
数组(array):一组标量值的序列,所有的标量值必须为同一类型
群组(group):多个setting的集合
列表(list):一组值(value)的序列,各个值可(value)以分别为不同的类型,其他的列表也可以包含其中。
#conf.cfg
name = "IT_book & EL_book";
inventory = {
IT_book = ({ title = "C";
author = "root";
price = 27.8;
count = 4;
},
{
title = "C++";
author = "ROOT";
price = 52.0;
count = 1;
}
);
EL_book = ({
title = "Elec";
price = 12.5;
}
);
};
hours = {
mon = { open = 9; close = 18; };
tue = { open = 9; close = 18; };
wed = { open = 9; close = 18; };
thu = { open = 9; close = 18; };
fri = { open = 9; close = 20; };
sat = { open = 9; close = 20; };
sun = { open = 11; close = 16; };
};
PI = 3.141592654;
misc:
{
pi=3.141592654;
bigint=9223372036854775807L;
columns=["LastName","FirstName","MI"];
bitmask=0x1FC3;
};
包含在配置中的某个setting可以用path来唯一定义,path用点号分隔连接多个名字(name),由最顶层的群组(group)开始,到setting自身结束。path中的每个名字都是一个setting的名字;如果这个setting没有名字,那是因为它是数组(array)或列表(list)中的一个元素。用方括号包含一个整型索引值可以用来表示它的名字。
例如上边的配置文件: 名为name的setting,指向它的path就是name;
IT_book里第一个title, path为inventory.IT_book.[0].title;
mon里边的open, 指向它的path就是hours.mon.open;
名为pi的setting, 指向它的path就是misc.pi或misc.[0];
#include <stdio.h>
#include <libconfig.h>
int conf_test(const char *name)
{
config_t cfg;
//初始化
config_init(&cfg);
//读取配置文件
if(!config_read_file(&cfg, name))
{
fprintf(stderr, " %s %d %s \n", config_error_file(&cfg),
config_error_line(&cfg), config_error_text(&cfg));
config_destroy(&cfg);
return -1;
}
//读取配置文件中的字符串标量值
const char *str;
if(config_lookup_string(&cfg, "name", &str ))
fprintf(stderr, " %s \n", str);
//读取容器中的内容
config_setting_t *setting;
setting = config_lookup(&cfg, "inventory.IT_book");
if(setting)
{
int count = config_setting_length(setting);
int i;
fprintf(stderr, " %s %s %s %s\n", "title", "author", "price", "count");
const char *cfg_title;
const char *cfg_author;
double cfg_price;
int cfg_count;
for(i = 0; i < count; ++i)
{
config_setting_t *IT_book = config_setting_get_elem(setting, i);
if(!(config_setting_lookup_string(IT_book, "title", &cfg_title)
&& config_setting_lookup_string(IT_book, "author", &cfg_author)
&& config_setting_lookup_float(IT_book, "price", &cfg_price)
&& config_setting_lookup_int(IT_book, "count", &cfg_count)))
continue;
fprintf(stderr, " %s %s %4.2f %d \n",\
cfg_title, cfg_author, cfg_price, cfg_count);
}
}
//读取hours数据
int mon_open;
if(!config_lookup_int(&cfg, "hours.mon.open", &mon_open))
fprintf(stderr, " %s -%d: %s \n", config_error_file(&cfg), config_error_line(&cfg),\
config_error_text(&cfg));
else
fprintf(stderr, " mon_open : %d \n", mon_open);
//读取标量值
double PI;
if(config_lookup_float(&cfg, "PI", &PI))
fprintf(stderr, " PI = %10.9f \n", PI);
//读取mis容器
double pi;
if(!config_lookup_float(&cfg, "misc.[0]", &pi))
fprintf(stderr, " %s -%d: %s \n", config_error_file(&cfg), config_error_line(&cfg),\
config_error_text(&cfg));
else
fprintf(stderr, " misc.pi = %10.7f \n", pi);
return 0;
}