遍历在C ++ ini文件,可能是使用boost :: property_tree :: ptree

2019-08-31 16:43发布

我的任务是微不足道的 - 我只需要解析这样的文件:

Apple = 1
Orange = 2
XYZ = 3950

但我不知道一组可用密钥。 我是比较解析这个文件很容易使用C#,让我演示的源代码:

    public static Dictionary<string, string> ReadParametersFromFile(string path)
    {
        string[] linesDirty = File.ReadAllLines(path);
        string[] lines = linesDirty.Where(
            str => !String.IsNullOrWhiteSpace(str) && !str.StartsWith("//")).ToArray();

        var dict = lines.Select(s => s.Split(new char[] { '=' }))
                        .ToDictionary(s => s[0].Trim(), s => s[1].Trim());
        return dict;
    }

现在我只需要用C ++做同样的事情。 我想使用boost::property_tree::ptree但似乎我只是不能在ini文件迭代。 这很容易读取ini文件:

boost::property_tree::ptree pt;
boost::property_tree::ini_parser::read_ini(path, pt);

但是,这是不可能遍历它,请参阅这个问题升压方案选择-获得部分的所有条目

现在的问题是 - 什么是写上面的C#代码模拟在C ++的最简单的方法?

Answer 1:

要直接回答你的问题: 当然迭代一个属性树是可能的 。 事实上,它是微不足道:

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>

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

    read_ini("input.txt", pt);

    for (auto& section : pt)
    {
        std::cout << '[' << section.first << "]\n";
        for (auto& key : section.second)
            std::cout << key.first << "=" << key.second.get_value<std::string>() << "\n";
    }
}

这导致输出,如:

[Cat1]
name1=100 #skipped
name2=200 \#not \\skipped
name3=dhfj dhjgfd
[Cat_2]
UsagePage=9
Usage=19
Offset=0x1204
[Cat_3]
UsagePage=12
Usage=39
Offset=0x12304

我已经写了使用非常全功能的ini文件解析器升压灵前:

  • 跨平台的方式来获得,其中给定的选项中找到一个INI文件的行号

它支持的注释(单线和块),报价,逃逸等

(作为奖励,它任选地记录所有被分析的元素,这是问题的被检体的确切源位置)。

你的目的,不过,我想我会升压电子书籍属性树。



Answer 2:

就目前而言,我已经简化问题了一下,离开了(反正看起来破我)征求意见的逻辑。

#include <map>
#include <fstream>
#include <iostream>
#include <string>

typedef std::pair<std::string, std::string> entry;

// This isn't officially allowed (it's an overload, not a specialization) but is
// fine with every compiler of which I'm aware.
namespace std {
std::istream &operator>>(std::istream &is,  entry &d) { 
    std::getline(is, d.first, '=');
    std::getline(is, d.second);
    return is;
}
}

int main() {
    // open an input file.
    std::ifstream in("myfile.ini");

    // read the file into our map:
    std::map<std::string, std::string> dict((std::istream_iterator<entry>(in)),
                                            std::istream_iterator<entry>());

    // Show what we read:
    for (entry const &e : dict) 
        std::cout << "Key: " << e.first << "\tvalue: " << e.second << "\n";
}

就个人而言,我想我会写评论跳绳作为过滤流缓冲,但对于那些不熟悉C ++标准库,它是开放的说法,这将是一个有点迂回的解决方案。 另一种可能性是一个comment_iterator是跳过一行的剩余部分,由指定的注释分隔符开始。 我不喜欢那个为好,但它可能在某些方面更简单。

请注意,我们真的写在这里的唯一代码是从文件中读取一个,单次进入pair 。 该istream_iterator从那里完成几乎一切。 因此,有一个在写你的函数的直接模拟真实的小点 - 我们刚刚从迭代器初始化地图,我们就大功告成了。



文章来源: iterate over ini file on c++, probably using boost::property_tree::ptree?
标签: c++ boost