首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用Boost解析ini文件

如何使用Boost解析ini文件
EN

Stack Overflow用户
提问于 2011-05-30 19:09:37
回答 4查看 71.3K关注 0票数 66

我有一个ini文件,其中包含一些样本值,如下所示:

代码语言:javascript
复制
[Section1]
Value1 = 10
Value2 = a_text_string

我正在尝试使用Boost加载这些值并将它们打印到我的应用程序中,但我不知道如何在C++中做到这一点。

我在这个论坛上搜索了一些例子(我总是使用C,所以我的C++不是很好),但我只找到了一些关于如何一次从文件中读取值的例子。

我只需要在需要的时候加载一个值,比如string = Section1.Value2,因为我不需要读取所有的值,只需要读取其中的一小部分即可。

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

使用Boost可以做到这一点吗?

目前,我使用的是以下代码:

代码语言:javascript
复制
#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;
   }

但这只是读取for循环中的所有值;相反,我只想在需要的时候读取单个值,而不需要在文件中插入值,因为它已经写入了我的程序中需要的所有值。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-05-30 20:38:30

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

代码语言:javascript
复制
#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;
票数 147
EN

Stack Overflow用户

发布于 2011-06-01 09:35:28

由于其简单的结构,解析INI文件很容易。使用AXE,我可以编写几行代码来解析部分、属性和注释:

代码语言:javascript
复制
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();

更详细的示例可以在Reference.pdf中找到

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

最后,我不确定避免读取整个文件会带来什么好处。INI文件通常很小,因为硬盘驱动器和多个缓冲系统无论如何都会读取一个或多个扇区(即使你只需要一个字节),所以我怀疑尝试部分读取文件(特别是重复读取)是否会有任何性能改善,可能正好相反。

票数 3
EN

Stack Overflow用户

发布于 2011-05-30 19:33:40

需要对文件进行解析,必须按顺序执行。因此,我只需读取整个文件,将所有值存储在某个集合(mapunordered_map,可能使用pair<section, key>作为键或使用映射的映射)中,并在需要时从那里获取它们。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6175502

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档