我開始使用YAML和yaml-cpp庫來解釋我的文件。我用自己的項目中的一些信息擴展了「怪物」例子。代碼和yaml文件在下面,但這是我的第一個問題:數據結構與yaml-cpp接口的設計技巧?
是否有必要將我將從項目中獲得的所有數據集中到一個大型結構中?在怪物示例中,從文檔doc [i]中讀取值很容易,因爲它是一個怪物列表。在我的例子中,我會列出一些列表,但也包括標量等等。我發現要做到這一點的唯一方法是創建一個技術上只有一個條目的列表(即頂部有一個' - '的文件,並且所有內容都被嵌入到一個塊中)。我認爲答案是採用一些重載操作符的'problemformulation'版本的內容,但是如果沒有該函數內的內容,我就無法正常工作。任何幫助或建議表示讚賞。
ea_test.cpp:
#include "yaml-cpp/yaml.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
struct Vec2{
double x, y;
};
struct DecVar{
std::string name;
std::string tag;
Vec2 range;
std::string description;
};
struct ProblemFormulation{
std::vector <DecVar> decvars;
int numrealizations;
};
void operator >> (const YAML::Node& node, Vec2& v) {
node[0] >> v.x;
node[1] >> v.y;
}
void operator >> (const YAML::Node& node, DecVar& decvar){
node["name"] >> decvar.name;
node["tag"] >> decvar.tag;
node["range"] >> decvar.range;
node["description"] >> decvar.description;
}
void operator >> (const YAML::Node& node, ProblemFormulation& problemformulation){
node["realizations"] >> problemformulation.numrealizations;
std::cout << " read realizations!" << std::endl;
const YAML::Node& decvarNode = node["decisions"];
for (unsigned int i = 0; i < decvarNode.size(); i++)
{
DecVar decvar;
decvarNode[i] >> decvar;
problemformulation.decvars.push_back(decvar);
}
}
int main()
{
std::ifstream fin("./ea.yaml");
YAML::Parser parser(fin);
YAML::Node doc;
parser.GetNextDocument(doc);
std::cout << "entering loop" << std::endl;
ProblemFormulation problemformulation;
for (unsigned int i = 0; i < doc.size(); i++)
{
doc[i] >> problemformulation;
}
return 0;
}
而且,ea.yaml:
-
realizations: 10
decisions:
- name: reservoir
tag: res_tag
range: [0, 1.0]
description: >
This is a description.
- name: flow
tag: flow_tag
range: [0, 2.0]
description: >
This is how much flow is in the system.
預先感謝您的幫助和提示!
編輯:我可能只會運行一個yaml文檔,並且只會創建一個問題表達式對象。我的代碼適應你爲列表做什麼,但只做一次。我想知道正確的方法,「只做一次」,因爲我認爲這將是更乾淨,並製作一個更好看的YAML文件(沒有所有的東西縮進一塊沒有理由)。
感謝您的幫助。我可能會有更多的問題,但稍後會將它們寫成完整的單獨的帖子。 – Joe 2012-02-09 20:21:26