如何使用Boost解析ini文件
我有一个 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;
}
但这只是读取 for
循环中的所有值;相反,我只想在需要时读取单个值,并且不需要在文件中插入值,因为它已经写有我的程序中需要的所有值。
I have a ini file which contains some sample values like:
[Section1]
Value1 = 10
Value2 = a_text_string
I'm trying to load these values and print them in my application with Boost but I don't understand how to do this in C++.
I searched in this forum in order to find some examples (I always used C and so I'm not very good in C++) but I found only examples about how to read values from file all at once.
I need to load just a single value when I want, like string = Section1.Value2
because I don't need to read all the values, but just few of them.
I'd like to load single values and to store them in variable in order to use them when I want in my application.
It is possible to do this with Boost?
At the moment, I'm using this code:
#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;
}
But this just read all the values in a for
loop; at the contrary I just want to read single values when I want and I don't need to insert values in the file, because it is already written with all the values which I need in my program.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您还可以使用 Boost.PropertyTree 读取 .ini 文件:
You can also use Boost.PropertyTree to read .ini files:
由于 INI 文件结构简单,解析 INI 文件很容易。使用 AX,我可以编写几行来解析部分、属性和注释:
更详细的示例可以在 Reference.pdf
关于不阅读整个文件,可以通过不同的方式来完成。首先,INI 格式的解析器至少需要前向迭代器,因此您不能使用流迭代器,因为它们是输入迭代器。您可以为具有所需迭代器的流创建一个单独的类(我过去使用滑动缓冲区编写了一个这样的类)。您可以使用内存映射文件。或者您可以使用动态缓冲区,从标准流中读取并提供给解析器,直到找到值。如果您不想拥有真正的解析器,并且不关心 INI 文件结构是否正确,您可以简单地在文件中搜索您的标记。输入迭代器就足够了。
最后,我不确定避免读取整个文件会带来什么好处。 INI 文件通常非常小,并且由于硬盘驱动器和多个缓冲系统无论如何都会读取一个或多个扇区(即使您只需要一个字节),所以我怀疑尝试部分读取文件是否会提高性能(尤其是重复做),可能恰恰相反。
Parsing INI files is easy due to their simple structure. Using AXE I can write in a few lines to parse sections, properties and comments:
More detailed example can be found in the Reference.pdf
Regarding not reading the whole file, it can be done in different ways. First of all, parser for INI format requires at least forward iterators, so you can't use stream iterators, since they are input iterators. You can either create a separate class for stream with required iterators (I wrote one such class in the past with sliding buffer). You can use memory mapped file. Or you can use a dynamic buffer, reading from the standard stream and supplying to parser until you found the values. If you don't want to have a real parser, and don't care if the INI file structure is correct or not, you can simply search for your tokens in the file. Input iterators would suffice for that.
Finally, I'm not sure that avoiding reading the whole file brings any advantages with it. INI files are typically pretty small, and since the hard drive and multiple buffering systems would read one or more sectors anyway (even if you need just one byte), so I doubt there would be any performance improvement by trying to read file partially (especially doing it repeatedly), probably the opposite.
该文件需要被解析,这必须按顺序完成。因此,我只需读取整个文件,将所有值存储在某个集合中(
map
或unordered_map
,可能使用pair< /code> 作为键或使用地图的地图)并在需要时从那里获取它们。
The file needs to be parsed, which has to be done sequentially. So I'd just read the whole file, store all the values in some collection (
map
orunordered_map
, probably, either usingpair<section, key>
as key or using map of maps) and fetch them from there when needed.我读过一篇关于使用 boost 方法进行 INI 解析的好文章,它被称为 INI 文件阅读器,使用精神库,作者:西尔维乌·西门。
这很简单。
I have read a nice article about INI-parsing with boost methods, it's called INI file reader using the spirit library by Silviu Simen.
It's simple one.