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

Posted

技术标签:

【中文标题】我可以读取输入数据并创建通用 C++ 数据结构吗?【英文标题】:Can I Read Input Data and create generalized C++ data structure? 【发布时间】:2016-02-25 01:35:07 【问题描述】:

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

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

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

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

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

很遗憾,由于其专有性质,我无法显示任何实际数据,但X.Y(1).Z 格式应该能够说明其要点。

【问题讨论】:

【参考方案1】:

您的问题没有具体说明,但让我想起了 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&lt;&gt; 的类型的情况下进行操作 请注意,'.' 是 Boost 属性树路径中的默认路径分隔符,这有点令人遗憾。因此查询的方式有点笨拙(例如使用tree::path_type("X(1).Y", '|') 而不仅仅是"X(1).Y"

【讨论】:

对不起,问题的规格不足。我试图在不违反此处有关敏感数据的任何规则的情况下尽可能详细地进行描述。对于我正在做的事情,这实际上看起来很有希望。我将不得不对其进行探索并提出任何问题(当然,the documentation 无法回答)。谢谢。

以上是关于我可以读取输入数据并创建通用 C++ 数据结构吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C++ 中读取来自网络摄像头的输入?

用 C++ 打开 2 个数据文件

我可以使用 Rexx 在 zos 中读取数据集的分配参数吗?

创建具有多个链接服务的通用数据工厂

C++ 唯一类名与命名空间

在 C++ 中可以有一个虚拟类型吗?