C++ 如何用Boost解析ini文件

C++ 如何用Boost解析ini文件,c++,parsing,boost,ini,C++,Parsing,Boost,Ini,我有一个ini文件,其中包含一些示例值,如: [Section1] Value1 = 10 Value2 = a_text_string 我试图加载这些值并在Boost中用我的应用程序打印它们,但我不明白如何在C++中实现这一点。 我在这个论坛上搜索了一些示例(我总是使用C,所以我对C++不是很在行),但我只找到了关于如何一次从文件中读取值的示例 如果需要,我只需要加载一个值,比如string=Section1.Value2,因为我不需要读取所有值,只需要读取其中的少数值 我希望加载单个值并将

我有一个ini文件,其中包含一些示例值,如:

[Section1]
Value1 = 10
Value2 = a_text_string
我试图加载这些值并在Boost中用我的应用程序打印它们,但我不明白如何在C++中实现这一点。 我在这个论坛上搜索了一些示例(我总是使用C,所以我对C++不是很在行),但我只找到了关于如何一次从文件中读取值的示例

如果需要,我只需要加载一个值,比如
string=Section1.Value2
,因为我不需要读取所有值,只需要读取其中的少数值

我希望加载单个值并将它们存储在变量中,以便在需要时在应用程序中使用它们

有可能用Boost实现这一点吗

目前,我正在使用以下代码:

#include <iostream>
#include <string>
#include <set>
#include <sstream>
#include <exception>
#include <fstream>
#include <boost/config.hpp>
#include <boost/program_options/detail/config_file.hpp>
#include <boost/program_options/parsers.hpp>

namespace pod = boost::program_options::detail;

int main()
{
   std::ifstream s("file.ini");
    if(!s)
    {
        std::cerr<<"error"<<std::endl;
        return 1;
    }

    std::set<std::string> options;
    options.insert("Test.a");
    options.insert("Test.b");
    options.insert("Test.c");

    for (boost::program_options::detail::config_file_iterator i(s, options), e ; i != e; ++i)
        std::cout << i->value[0] << std::endl;
   }
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
名称空间pod=boost::program_options::detail;
int main()
{
std::ifstream(“file.ini”);
如果(!s)
{

std::cerr文件需要解析,必须按顺序进行解析。因此,我只需读取整个文件,将所有值存储在某个集合中(
map
unordered\u map
,可能使用
pair
作为键或使用map of map)并在需要时从那里获取它们。

您还可以使用Boost.PropertyTree读取.ini文件:

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

...

boost::property_tree::ptree pt;
boost::property_tree::ini_parser::read_ini("config.ini", pt);
std::cout << pt.get<std::string>("Section1.Value1") << std::endl;
std::cout << pt.get<std::string>("Section1.Value2") << std::endl;
#包括
#包括
...
boost::property_tree::ptree pt;
boost::property_tree::ini_parser::read_ini(“config.ini”,pt);

std::cout解析INI文件很容易,因为它们的结构很简单。使用AXE,我可以写几行来解析节、属性和注释:

auto trailing_spaces = *space & endl;
auto section = '[' & r_alnumstr() & ']';
auto name = +(r_any() - '=' - endl - space);
auto value = '"' & *("\\\"" | r_any() - '"') & '"'
   | *(r_any() - trailing_spaces);
auto property = *space & name & *space & '=' & *space 
    & value & trailing_spaces;
auto comment = ';' & *(r_any() - endl) & endl;
auto ini_file = *comment & *(section & *(prop_line | comment)) & r_end();
更详细的示例可以在

关于不读取整个文件,可以用不同的方法来完成。首先,INI格式的解析器至少需要前向迭代器,所以不能使用流迭代器,因为它们是输入迭代器。您可以使用所需的迭代器为流创建单独的类(我在过去使用滑动缓冲区编写了一个这样的类)。您可以使用内存映射文件。或者您可以使用动态缓冲区,从标准流读取数据并提供给解析器,直到找到值。如果您不想拥有真正的解析器,也不关心INI文件结构是否正确,您只需在文件中搜索您的标记。输入迭代器就足够了


最后,我不确定避免读取整个文件是否会带来任何好处。INI文件通常非常小,而且由于硬盘驱动器和多缓冲系统无论如何都会读取一个或多个扇区(即使您只需要一个字节),因此我怀疑尝试部分读取文件是否会有任何性能改进(尤其是反复进行),可能正好相反。

我读了一篇关于使用boost方法进行INI解析的文章,它的名字是


它很简单。

使用“经典”风格的spirit库也很旧。+1非所有如果我不知道某些可用键集,但我仍然希望获得完整的键=值对列表,例如,如果不使用“Section1.Value1”和“Section1.Value2”,您将如何重写程序常量?upd:我发现这个问题是因为如果不编写自定义代码是不可能的…@javapowered您发现的问题是关于Boost.Program_选项的,而不是关于Boost.PropertyTree的。现在问题解决了:我一直与Boost.PropertyTree有关的问题是在节名和值名之间使用。True INI files支持包含“.”字符的节名和值名。更好的分隔符应该是/或\。不可打印的字符,如bell字符(\007)会更好。是否可以自定义此行为?+1作为对C++11有用的解析库的参考: