【发布时间】:2015-03-24 07:49:44
【问题描述】:
我知道我似乎有回答自己问题的习惯,但到目前为止,我一直被困在这个问题上,需要一些帮助。
我已经编写了一些代码来将 json 格式的文件加载到类系统中。我把所有的代码放在这里: https://github.com/tomzooi/readreq
简而言之,我想做的是: 首先,我创建了一些代码,可以读取“需求”文件并使用 class.h 中的 Requirement 类存储它 这再次我可以以人类可读的格式输出到屏幕或存储在一个 json 文件中。这行得通。
然后我希望能够读取 JSON 文件并再次使用相同的 Requirement 对象将其存储在内存中,但这并不能很好地工作(到目前为止)。
现在的主要问题是我正在遍历属性树的部分,这主要是在这个递归函数中完成的:
void display(const int depth, const boost::property_tree::ptree& tree, Requirement * cur_requirement, std::vector<Requirement> &requirements) {
unsigned int count;
std::string label,level,description;
boost::property_tree::ptree kids = tree.get_child("");
bool godown = false;
for (const auto& v : kids) { // v is of type ptree::value_type
std::cout << std::string("").assign(depth+1,'#') << " ";
std::string nodestr = tree.get<std::string>(v.first);
//std::cout << v.first << " = " << nodestr << std::endl;
if (v.first == "label") {
label = nodestr;
std::cout << "lbl: " << label << std::endl;
}
else if(v.first == "level") {
//std::cout << "LABEL!";
level = nodestr;
std::cout << "lvl: " << level << std::endl;
}
else if(v.first == "description") {
description = nodestr;
std::cout << "dsc: " << description << std::endl;
}
else if(v.first == "children") { //going down, store stuff first
if(depth == 0) { //zero depth
std::cout << "zero depth...";
requirements.emplace_back(level, description, label,cur_requirement);
cur_requirement = &requirements.back();
}
else { //one or higher depth
std::cout << "at depth " << depth << "..." << std::flush;
cur_requirement->children.emplace_back(level,description,label,cur_requirement->parent);
cur_requirement = &cur_requirement->children.back();
}
std::cout << "going down" << std::endl;
//cur_requirement = &cur_requirement->children.back();
display(depth+1, v.second, cur_requirement,requirements);
}
else if(v.first == "") {
std::cout << "empty v.first ... level: " << level << std::endl;
if(depth == 0) { //zero depth
std::cout << "store at zero depth...";
requirements.emplace_back(level, description, label,cur_requirement);
cur_requirement = &requirements.back();
}
else { //one or higher depth
std::cout << "store at depth " << depth << " : " << level << "--" << description << std::flush;
cur_requirement->children.emplace_back(level,description,label,cur_requirement->parent);
//cur_requirement = &cur_requirement->children.back();
}
std:: cout << " going to next " << std::endl;
//cur_requirement = &cur_requirement->children.back();
display(depth, v.second, cur_requirement,requirements);
}
else {
std:: cout << "what else..." << std::endl;
}
// v.first is the name of the child
// v.second is the child tree
}
};
我目前得到的输出是这样的:
[tom@tomtop dev]$ ./readreq The_system.F.req.json
name: The system prefix: F
# lvl: should
# dsc: very well performance wise
# lbl: goperf
# zero depth...going down
## empty v.first ... level:
store at depth 1 : -- going to next
## lvl: should
## dsc: be listening to spaces as well
## lbl: lisspace
## empty v.first ... level:
store at depth 1 : -- going to next
## lvl: will
## dsc: a lot of levels back down again
## at depth 1...going down
### empty v.first ... level:
store at depth 2 : -- going to next
### lvl: empty
### dsc: empty
### lbl: empty
### at depth 2...going down
#### empty v.first ... level:
store at depth 3 : -- going to next
#### lvl: can
#### dsc: skip all the way back here
#### lbl: skiphere
#### empty v.first ... level:
store at depth 3 : -- going to next
#### lvl: can
#### dsc: take three linestr
#### lbl: threelines
level: should description:very well performance wise label: goperf
level: description: label:
level: description: label:
level: will description:a lot of levels back down again label:
level: description: label:
level: empty description:empty label: empty
level: description: label:
level: description: label:
其中大部分是有道理的,而且大部分似乎都有效,但有一件事让我感到困惑。属性树的组织方式是在每个“子”之前以及数组元素之间都有一个“空”节点。 (如果我错了,请纠正我,我对属性树不太熟悉)。
所以当我遇到“children”或“”(空)元素后,我想存储我之前收集的数据,存储在变量级别、描述和标签中。
这里是有趣的部分,当元素是“孩子”时,这就像一个魅力,然而,当元素是“”时,突然变量为空,即使变量没有重新初始化,我也没有深入到属性树中,我只迭代到 for 循环中的下一个“孩子”。
所以我希望输出是这样的:
## lvl: should
## dsc: be listening to spaces as well
## lbl: lisspace
## empty v.first ... level: should
store at depth 1 : should -- be listening to spaces as well going to next
最后一行(由
生成std::cout
) 显示:
store at depth 1 : -- going to next
给人的印象是标签、描述和级别在某种程度上是空的,并且没有任何地方可以使它们空的。
因此,如果有人能向我解释这种神秘的行为,我将非常高兴。
【问题讨论】:
-
您是否尝试过使用调试器查看“神秘行为”首先发生在哪里?
-
到目前为止,我注意到当有一个没有“孩子”的 JSON 数组元素时会发生这种行为,这意味着每当属性树遇到“空” v.first (将节点声明到下一个元素)它突然“清空”标签、级别和描述字符串变量,原因不明。至于调试器,我来自为微控制器和其他基本编程编写 C 语言,所以不,我会看看,但我不确定在哪里寻找......