我可以读取输入数据并创建通用的C ++数据结构吗?

时间:2016-02-25 01:35:08

标签: c++ string dictionary boost input

我正在尝试推广数据结构(在C ++中),这样我就可以将输入数据转换为更有用的形式,而且我尝试的每种不同方法都会遇到明显的问题,使其无法使用。我在这里的研究有助于指出这些问题,但它并没有帮助我找到问题的解决方案。

为了简洁起见,这是实际问题。每个数据点都是一对 - 一个字符串和一个未知数据类型(很可能是字符串,双精度或整数)。第一个字符串将是字符X.Y(1).Z,但该格式未标准化(例如,某些格式将显示为X.Y.Z(A)(1)X(1).Y)。 (parens中的值有向量索引作为整数或映射为不同的“子变量”,如[A,B,C]。)

我正在尝试将其重组为一种“动态”的数据结构树,以便我可以轻松访问它(即不参考原始的,可能很长的字符串)并且通常(我不知道字符串在编译时,因此不能简单地为它准备)。

到目前为止,我已经决定使用unordered_map<string, (some type T here)>作为“树”的根,而pair<(some type T), boost::variant>类型似乎是处理底部“叶子”的合适方式。 / p>

我的问题是:有什么方法可以将结构从顶部的unordered_map到中间级别一直概括到底部的pair,这样就可以了对于任何字符串 - 无论是X.Y.Z还是更复杂的情况?或者我是否需要在更高级别编写我的泛化(例如,指向具有多个可能派生化身的通用数据对象的指针)?或者我完全走错了轨道?

不幸的是,由于其专有性质,我无法显示任何实际数据,但X.Y(1).Z格式应该提供它的要点。

1 个答案:

答案 0 :(得分:0)

您的问题未明确,但让我想起了Boost PropertyTree - 它能够以各种格式读取通用值树结构输入。

如果您可以稍微改变一下格式,您可以快速获得结果。一个例子说千言万语:

输入

; an int
X.Y(1).Z 42

; a float
X.Y.Z(A)(1) 3.1415926

; a string
X(1).Y "Hello world"

subtree {
    X(2).Y Bye
}

程序

<强> Live On Coliru

#include <iostream>
#include <boost/property_tree/info_parser.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <boost/property_tree/json_parser.hpp>

int main()
{
    using tree = boost::property_tree::ptree;
    tree pt;

    read_info("input.txt", pt);

    std::cout << "The float is " << pt.get<double>(tree::path_type("X.Y.Z(A)(1)", '|')) << "\n";

    write_ini(std::cout  << "\nINI:\n",  pt);
    write_info(std::cout << "\nINFO:\n", pt);
    write_json(std::cout << "\nJSON:\n", pt);

    std::cout << "Greeting: " << pt.get(tree::path_type("subtree|X(2).Y", '|'), "No greeting") << "\n";
    std::cout << "Final words: " << pt.get(tree::path_type("subtree|missing|final.words", '|'), "No final words") << "\n";
}

输出

The float is 3.14159

INI:
X.Y(1).Z=42
X.Y.Z(A)(1)=3.1415926
X(1).Y=Hello world
[subtree]
X(2).Y=Bye

INFO:
X.Y(1).Z 42
X.Y.Z(A)(1) 3.1415926
X(1).Y "Hello world"
subtree
{
    X(2).Y Bye
}

JSON:
{
    "X.Y(1).Z": "42",
    "X.Y.Z(A)(1)": "3.1415926",
    "X(1).Y": "Hello world",
    "subtree": {
        "X(2).Y": "Bye"
    }
}

Greeting: Bye
Final words: No final words

注意:

  • 请注意,如果您传递了合适的默认值
  • ,则无需指定get<>的类型即可
  • 请注意,'.'是Boost属性树路径中的默认路径分隔符,这有点不幸。因此,查询的方式有点笨拙(tree::path_type("X(1).Y", '|')而不是"X(1).Y",例如。)