libconfig初识

Posted ych9527

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了libconfig初识相关的知识,希望对你有一定的参考价值。

一、是什么

  • 是一个解析配置文件的C/C++库

二、为什么需要

  • 通常业务代码的代码量是非常大的,如果没有配置文件,那么所有的东西都是写死的,在后续的维护过程之中,进行修改就是非常麻烦的一件事
  • 如果有配置文件,我们可以通过读取配置文件来完成某些动作,这样就提高了代码的可迭代和可维护性
  • libconfig就是提供操控配置文件的一个库。如果我们不适用库来对配置文件进行读取,那么是非常麻烦的一件事。比如我们需要fopen一个文件,然后对文件指针进行操作,以及一些特殊情况的处理,libconfig将这些功能都给包装了起来,用户直接调用API接口即可

三、使用说明

3.1功能说明

  • lbconfig支持结构化、层次化的配置。这些配置可以从文件中读取或写入文件,也可以在内存中操作

3.2配置文件构成

  • setting

    • 一个配置由setting构成
    • 常见格式为 name=value; 或者 name: value; 结尾分号必须有,空格会被忽略
  • value的类型

    • 标量型(scalarvalue)

      • 整形

        • 可以用两种方式表示:十进制数,由0-9组成,并且可以带+或-;十六进制数,0x打头并且用十六进制数表示
      • 64位整形

        • 表示方法和整型值基本一致,但是需要在最后加上L来表明它是一个64位整型值。比如0L表示一个64位的0值
      • 浮点数

        • 浮点值由一个十进制数,可以带正负符号,然后带上一个可选的指数。这个可选的指数又由字母E或者e加上一个可选的正负符号再加上具体的数字
      • 布尔值

        • 布尔值的取值只能是true和false,包括另外大小写混合的写法,比如tRue或FaLSe
      • 字符串

        • 字符串是由双引号引起来的任意文本

        • 字符串里的双引号由转义符\\”替代,其他的转义符比如\\、\\f、\\r、\\n、\\t都可以被辨认,并且与通常的理解一致

        • 相邻的两个字符串会被自动连接,下面的三种写法的字符串是等价的

          "123123213123424323"
            
           "123123213"
           "123424323" 
            
           "123123213"//注释
           "123424323"
          
    • 数组(array)

      • 数组的格式为[value,value]
      • 一个数组可以有零个或者多个元素,但是每个元素都必须是相同类型的标量值
    • 群组(group)

      • 多个setting的集合,setting1,setting2,…
      • 一个群组可以有零个或者多个元素,但是每个元素都必须是相同类型的标量值
    • 列表(list)

      • 列表格式为(value,value…)
      • 一个列表可以有零个或者多个元素,而且每个元素可以分别是标量值、数组、群组或其他列表
  • 注释

    • 脚本风格、C/C++风格的注释都是可以用的
    三种风格的注释都是可以用的
    # 注释
    //注释
    /*注释*/
    
    • 注释可以在字符串中出现,在读取配置文件的时候,注释的内容会被忽略。写回配置文件时,原来的注释也会丢失
  • 包含指令

    • 一个配置文件可能包含了另外一个配置文件的内容,这时就要用到包含指令
    • 格式为@include“filename”
    • 包含文件最大嵌套十层,突破这个限制会产生一个分析错误
    • 与注释类似,包含指令在配置文件被分析之前就已经被处理了,所以当配置写回文件的时候,包含指令不会被保留
  • 举例代码说明

    #Exampleapplicationconfigurationfile
    
    version="1.0"; //这是一个setting   path=version
    
    application: //application是一个群组
    
    
    window: //windows也是一个群组
    
    
    
    title="MyApplication";//setting
    
    size=w=640;h=480;;//群组
    
    pos=x=350;y=250;;//群组     名为x的setting, path=applivation.window.pos.x
    ;
    
    list=(("abc",123,true),1.234,(/*anemptylist*/));//list嵌套
    
    books=( //列表
    
      //这个群组没有名字,因为它是列表中的元素
      //他的名字可以标识为books[1]
    
    
    title="TreasureIsland";
    
    author="RobertLouisStevenson";
    
    price=29.95;
    
    qty=5;
    
    ,
    
    
    
    title="SnowCrash";   //path=applivation.books[1].title
    
    author="NealStephenson";
    
    price=9.99;
    
    qty=8;
    
    
    
    );
    
    misc:
    
    
    
    pi=3.141592654;//浮点数
    
    bigint=9223372036854775807L;//64整形
    
    columns=["LastName","FirstName","MI"];//数组,元素都是相同的
    
    bitmask=0x1FC3;//16进制
    
    ;
    ;
    
  • 命名

    • 包含在配置中的某个setting可以用path来唯一定义,path用点号分隔连接多个名字(name),由最顶层的群组(group)开始,到setting自身结束
    • path中的每个名字都是一个setting的名字;如果这个setting没有名字,那是因为它是数组(array)或列表(list)中的一个元素。用方括号包含一个整型索引值可以用来表示它的名字
    • 下面展示几个setting的path
      • version:path=varsion;
      • x:application.window.pos.x;
      • title:application.books.[1].title;
  • 注意点

    • 一个值的类型由它本身决定,没有关键字,比如被双引号围起来就是字符串,true就是bool值…
    • 如果出现了value规定以外的类型就是错误的
    • 所有name都是大小写敏感的。并且只能由数字字母、横杠(-),下横杠(_)和星号(*)组成,而且必须以字母或星号开头。其他字符都是非法的
    • 在C和C++中,整型、64位整型、浮点数和字符串分别被映射为int、longlong、double和constchar *。布尔型在C中被映射为int,在C++中被映射为boo

3.2C++版本常见API接口说明

  • *bool lookupValue (const char path, int &value)

    • 这个函数重载,说明参数为char *版本的对应也有 参数为string版本的,参数2为各种类型的
    • 这些是使用给定 path 查找设置值的便捷方法 。如果找到了设置并且是适当的类型,则该值存储在 value 中 并且该方法返回 true 。否则, value 保持不变并且该方法返回 false 。这些方法不会抛出异常
  • bool exists ( const std::string &path)

    • 同样也有重载的存在exists ( const char *path)
    • 判断是否存在某项配置名,返回true则存在,false不存在,这些方法不会抛异常
  • *Setting & lookup(const char path) const;

    • 定位由路径指定的Setting。 如果未找到请求的Setting,则抛出 SettingNotFoundException。返回值为Setting对应的value
class LIBCONFIGXX_API Config

public:

    Config();  //默认构造函数
    virtual ~Config(); //析构函数
    ...
    void read(FILE *stream); //以文件流的方式读取配置
    void write(FILE *stream) const;//以文件流的方式修改配置

    void readFile(const char *filename); //读取指定文件名的配置
    void writeFile(const char *filename);//修改指定文件名的配置

    Setting & lookup(const char *path) const; //返回path指定setting的value值的引用
    inline Setting & lookup(const std::string &path) const
     return(lookup(path.c_str())); 

    bool exists(const char *path) const; //判断是否存在某项配置名
    inline bool exists(const std::string &path) const
     return(exists(path.c_str())); 

    //查找指定节点的值
    bool lookupValue(const char *path, bool &value) const;
    bool lookupValue(const char *path, int &value) const;
    bool lookupValue(const char *path, unsigned int &value) const;
    ...

    Setting & getRoot() const;//获取配置的根节点
    ...
private:

    ...
    config_t *_config;
    Setting::Format _defaultFormat;
    //禁止拷贝和赋值
    Config(const Config& other); // not supported
    Config& operator=(const Config& other); // not supported
;


//获取/修改配置
class LIBCONFIGXX_API Setting

friend class Config;
...

public:

    virtual ~Setting();

    inline Type getType() const  return(_type); 
	
  //lookup返回的是value值,Setting可以直接被转化为各种类型
    Setting & lookup(const char *path) const;
    inline Setting & lookup(const std::string &path) const
     return(lookup(path.c_str())); 

    Setting & operator[](const char *name) const;
    Setting & operator[](int index) const;

    //从readFile的结果中查找path的值,并将其赋给指定的类型vlaue
    bool lookupValue(const char *name, bool &value) const;
    bool lookupValue(const char *name, int &value) const;
    bool lookupValue(const char *name, unsigned int &value) const;
    bool lookupValue(const char *name, long long &value) const;
    bool lookupValue(const char *name, unsigned long long &value) const;
    ...

    //用于添加指定类型的节点
     Setting & add(const char *name, Type type);

    inline Setting & add(const std::string &name, Type type)
     return(add(name.c_str(), type)); 

    Setting & add(Type type);

    bool exists(const char *name) const;

    //判断某项配置是否存在
    inline bool exists(const std::string &name) const
     return(exists(name.c_str())); 

    ...
private:

    config_setting_t *_setting;
    ...
    Setting(const Setting& other); // not supported
    Setting& operator=(const Setting& other); // not supported
;


//其他相关
迭代器
class SettingIterator;
class SettingConstIterator;
各种异常捕获类
class SettingTypeException;
class SettingNotFoundException;
class SettingNameException;
class FileIOException;
class ParseException;

以上是关于libconfig初识的主要内容,如果未能解决你的问题,请参考以下文章

libconfig初识

使用 libconfig 传递组元素时出现分段错误

初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段

初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段

C & libconfig: config_lookup_bool 返回 CONFIG_FALSE

如何使用 libconfig 读取一个对象中的多个配置文件?