C++使用yaml配置文件

使用配置文件有利于我们灵活配置工程,解决大量重复劳动,也方便调试

读取config.yaml文件中参数内容,并赋值给程序中相关参数。

 

如果不存在key,会报错:

terminate called after throwing an instance of 'YAML::TypedBadConversion<int>'

  what():  yaml-cpp: error at line 0, column 0: bad conversion

已放弃 (核心已转储)

 

示例:

yaml_test.cpp

#include <iostream>
#include "yaml-cpp/yaml.h"
#include <fstream>
 
using namespace std;
 
typedef struct
{
  int cpp;
  int java;
  int android;
  int python;

}Skills;


typedef struct
{
    string name;
    string sex;
    int age;
    Skills skills;

} Config;



int test_base()
{
    YAML::Node config;
    try{
         config = YAML::LoadFile("../config.yaml");
    }catch(YAML::BadFile &e){
        std::cout<<"read error!"<<std::endl;
        return -1;
    }
    
    cout << "Node type " << config.Type() << endl;
    cout << "skills type " << config["skills"].Type() << endl;
 
    //可以用string类型作为下表,读取参数
    string age = "age";
    cout << "age when string is label:" << config[age].as<int>() << endl;
 
    cout << "name:" << config["name"].as<string>() << endl;
    cout << "sex:" << config["sex"].as<string>() << endl;
    cout << "age:" << config["age"].as<int>() << endl;
 
    //读取不存在的node值,报YAML::TypedBadConversion异常
    try{
        string label = config["label"].as<string>();
    }catch(YAML::TypedBadConversion<string> &e){
        std::cout<<"label node is NULL"<<std::endl;
    }//TypedBadConversion是模板类,读取什么类型的参数就传入什么类型
 
 
    cout << "skills cpp:" << config["skills"]["cpp"].as<int>() << endl;
    cout << "skills java:" << config["skills"]["java"].as<int>() << endl;
    cout << "skills android:" << config["skills"]["android"].as<int>() << endl;
    cout << "skills python:" << config["skills"]["python"].as<int>() << endl;
 
    for(YAML::const_iterator it= config["skills"].begin(); it != config["skills"].end();++it)
    {
        cout << it->first.as<string>() << ":" << it->second.as<int>() << endl;
    }
 
    YAML::Node test1 = YAML::Load("[1,2,3,4]");
    cout << " Type: " << test1.Type() << endl;
 
    YAML::Node test2 = YAML::Load("1");
    cout << " Type: " << test2.Type() << endl;
 
    YAML::Node test3 = YAML::Load("{'id':1,'degree':'senior'}");
    cout << " Type: " << test3.Type() << endl;
 
    ofstream fout("./testconfig.yaml"); //保存config为yaml文件
 
    config["score"] = 99;//添加新元素
 
    fout << config;
 
    fout.close();
 
    return 0;
}



int use_yaml_config()
{
    YAML::Node config;
    try{
         config = YAML::LoadFile("../config.yaml");
    }catch(YAML::BadFile &e){
        std::cout<<"read error!"<<std::endl;
        return -1;
    }

    Config param;


    //提取, 赋值
    param.age = config["age"].as<int>();
    param.name = config["name"].as<string>();
    param.sex = config["sex"].as<string>();

    param.skills.android = config["skills"]["android"].as<int>();
    param.skills.java = config["skills"]["java"].as<int>();
    param.skills.python = config["skills"]["python"].as<int>();
    param.skills.cpp = config["skills"]["cpp"].as<int>();


    //查看结果
    cout<< " param.age = "<<param.age <<endl;
    cout<< " param.name = "<<param.name <<endl;
    cout<< " param.sex = "<<param.sex <<endl;

    cout<< "param.skills.android = "<<param.skills.android <<endl;
    cout<< " param.skills.java = "<<param.skills.java <<endl;
    cout<< " param.skills.python = "<<param.skills.python <<endl;
    cout<< " param.skills.cpp = "<<param.skills.cpp <<endl;

    return 0;
}



int main(int argc,char** argv)
{

    use_yaml_config();

    return 0;
}

config.yaml

name: frank
sex: male
age: 18

skills: 
  cpp: 1
  java: 2
  android: 3
  python: 4

yaml 中的内容,:后面一定要加空格

CMakeLists.txt 配置


cmake_minimum_required(VERSION 3.2)
project(yaml_test)
add_definitions(-std=c++11)


find_package(yaml-cpp CONFIG REQUIRED)

set(SRCS ./src/yaml_test.cpp)

add_executable(yamltest ${SRCS})

# depend on catkin package

target_link_libraries(yamltest ${catkin_LIBRARIES} yaml-cpp) 


 

mkdir build
cd build
cmake ..
make
./yamltest

执行结果:

yuan@linx-c:~/VSCode/CPP_Learning/yaml/yaml_test/build$ ./yamltest 
 param.age = 18
 param.name = frank
 param.sex = male
param.skills.android = 3
 param.skills.java = 2
 param.skills.python = 4
 param.skills.cpp = 1

参考:

C++ 解析yaml文件的使用方法 https://blog.youkuaiyun.com/sunlin972913894/article/details/103038082

c++ 开发中利用yaml-cpp读写yaml配置文件 https://blog.youkuaiyun.com/briblue/article/details/89515470

 

Node 是 yaml-cpp 中的核心概念,它用于存储解析后的 yaml 信息。

yaml 支持 Scalar、List、Map 类型,yaml-cpp 通过 NodeType 定义了 Node 的可能类型。

namespace YAML {
struct NodeType {
  enum value { Undefined, Null, Scalar, Sequence, Map };
};
}

对应未定义、空、标量、序列、字典。

 

### 创建 YAML 配置文件的指南 YAML 是一种轻量级的人类可读数据序列化格式,适用于配置文件、日志记录以及许多其他用途。以下是创建 YAML 配置文件的详细指南和示例。 #### 1. 基础概念 YAML 使用缩进表示层级结构,不允许使用制表符(Tab),只接受空格作为缩进字符[^2]。每一层通常采用两个空格进行缩进。 #### 2. 字面量与键值对 最基本的 YAML 结构是由键值对组成,形式为 `key: value`。例如: ```yaml name: John Doe age: 30 email: john.doe@example.com ``` #### 3. 列表 列表可以通过 `-` 符号来定义,适合存储一组有序或无序的数据项。例如: ```yaml hobbies: - Reading - Traveling - Coding ``` #### 4. 映射与嵌套 映射可以包含更复杂的嵌套结构,用于描述多层次的对象关系。例如: ```yaml user: name: Jane Smith age: 25 address: street: 123 Main St city: Springfield zip: 62704 ``` #### 5. 多文档支持 YAML 支持在一个文件中定义多个独立的文档,通过 `---` 分隔符实现。例如: ```yaml --- name: Document One content: This is the first document. --- name: Document Two content: This is the second document. ``` #### 6. 注释 可以在 YAML 文件中添加注释以解释特定字段的作用。注释以 `#` 开始,后续内容会被忽略。例如: ```yaml # 用户基本信息 username: admin password: secret # 密码应加密保存 ``` #### 7. 实际应用场景 以下是一个 Kubernetes Deployment 的 YAML 配置文件示例[^3],展示了如何定义一个运行 Nginx 容器的应用程序部署: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 ``` #### 8. 在不同编程语言中的解析 不同的编程语言提供了相应的库来处理 YAML 文件。例如,在 C++ 中可以使用 `yaml-cpp` 库[^1];而在 Go 语言中,则有专门的支持包可用于解析和生成 YAML 数据。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值