用 C++ 创建一个简单的配置文件和解析器;
我正在尝试创建一个简单的配置文件,
url = http://mysite.com
file = main.exe
true = 0
在程序运行时看起来像这样,我希望它将配置设置加载到下面列出的程序变量中。
string url, file;
bool true_false;
我做了一些研究,这个链接似乎有帮助(nucleon的帖子)但我似乎无法让它发挥作用,而且它太复杂了,我无法理解。有一个简单的方法可以做到这一点吗?我可以使用 ifstream 加载文件,但这只是我自己所能做到的。谢谢!
I am trying to create a simple configuration file that looks like this
url = http://mysite.com
file = main.exe
true = 0
when the program runs, I would like it to load the configuration settings into the programs variables listed below.
string url, file;
bool true_false;
I have done some research and this link seemed to help (nucleon's post) but I can't seem to get it to work and it is too complicated to understand on my part. Is there a simple way of doing this? I can load the file using ifstream
but that is as far as I can get on my own. Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(15)
这是配置文件中“=”符号和数据之间的空格的简单解决方法。从“=”号后面的位置分配给 istringstream,并且在从中读取时,任何前导空格都会被忽略。
注意:在循环中使用 istringstream 时,请确保在为其分配新字符串之前调用clear()。
Here is a simple work around for white space between the '=' sign and the data, in the config file. Assign to the istringstream from the location after the '=' sign and when reading from it, any leading white space is ignored.
Note: while using an istringstream in a loop, make sure you call clear() before assigning a new string to it.
我想推荐一个单头 C++ 11 YAML解析器mini-yaml。
取自上述存储库的快速入门示例。
file.txt
.cpp
输出
I would like to recommend a single header C++ 11 YAML parser mini-yaml.
A quick-start example taken from the above repository.
file.txt
.cpp
Output
没有人提到
。我更喜欢它们,因为它们非常易于阅读并且不易出错。微量元素:No one mentioned
<regex>
. I prefer them since they are really easy to read and less error prone. MWE:SimpleConfigFile 是一个库,它完全可以满足您的需求,并且使用起来非常简单。
以下程序读取先前的配置文件:
函数
CFG::ReadFile
使用可变参数模板。这样,您可以传递要读取的变量,并使用相应的类型以适当的方式读取数据。SimpleConfigFile is a library that does exactly what you require and it is very simple to use.
The following program reads the previous configuration file:
The function
CFG::ReadFile
uses variadic templates. This way, you can pass the variables you want to read and the corresponding type is used for reading the data in the appropriate way.使用 Shan 的上述答案,我做了一些简单的修改,以便从文件中轻松读取数据,例如:单行中的多个输入,输入后带有“#”的注释选项。
以下是输入文件
config.txt
这是代码,
Using the above answer by Shan, I did some simple modification for easy data reading from files like- multiple inputs in a single line, option for comment with '#' after inputs.
The following is the input file
config.txt
Here is the code,
一般来说,分两个阶段解析此类典型配置文件是最简单的:首先读取各行,然后逐一解析它们。
在 C++ 中,可以使用 std::getline() 从流中读取行。虽然默认情况下它将读取到下一个
'\n'
(它将消耗但不返回),您也可以向它传递一些其他分隔符,这使其成为读取的良好候选者up-to-some-char,如示例中的=
。为简单起见,以下假设
=
没有被空格包围。如果您想在这些位置允许空格,则必须策略性地放置is >>> 。 std::ws
在读取值之前删除键中的尾随空格。然而,在我看来,语法中增加的一点灵活性对于配置文件阅读器来说并不值得这么麻烦。(添加错误处理留给读者作为练习。)
In general, it's easiest to parse such typical config files in two stages: first read the lines, and then parse those one by one.
In C++, lines can be read from a stream using
std::getline()
. While by default it will read up to the next'\n'
(which it will consume, but not return), you can pass it some other delimiter, too, which makes it a good candidate for reading up-to-some-char, like=
in your example.For simplicity, the following presumes that the
=
are not surrounded by whitespace. If you want to allow whitespaces at these positions, you will have to strategically placeis >> std::ws
before reading the value and remove trailing whitespaces from the keys. However, IMO the little added flexibility in the syntax is not worth the hassle for a config file reader.(Adding error handling is left as an exercise to the reader.)
正如其他人指出的那样,使用现有的配置文件解析器库而不是重新发明轮子可能会减少工作量。
例如,如果您决定使用 Config4Cpp 库(我维护的),那么您的配置文件语法将是略有不同(在值两边加上双引号并用分号终止赋值语句),如下例所示:
以下程序解析上述配置文件,将所需的值复制到变量中并打印它们:
Config4Cpp 网站 提供了全面的文档,但仅阅读“入门指南”的第 2 章和第 3 章就足以满足您的需要需要。
As others have pointed out, it will probably be less work to make use of an existing configuration-file parser library rather than re-invent the wheel.
For example, if you decide to use the Config4Cpp library (which I maintain), then your configuration file syntax will be slightly different (put double quotes around values and terminate assignment statements with a semicolon) as shown in the example below:
The following program parses the above configuration file, copies the desired values into variables and prints them:
The Config4Cpp website provides comprehensive documentation, but reading just Chapters 2 and 3 of the "Getting Started Guide" should be more than sufficient for your needs.
libconfig 非常简单,而且更好的是,它使用伪 json符号以获得更好的可读性。
在 Ubuntu 上易于安装:
sudo apt-get install libconfig++8-dev
和链接:
-lconfig++
libconfig is very easy, and what's better, it uses a pseudo json notation for better readability.
Easy to install on Ubuntu:
sudo apt-get install libconfig++8-dev
and link:
-lconfig++
一种简单的方法可能如下所示:
现在您可以从程序中任何位置的全局
options
映射访问每个选项值。如果您想要可转换性,可以将映射类型设置为boost::variant。A naive approach could look like this:
Now you can access each option value from the global
options
map anywhere in your program. If you want castability, you could make the mapped type aboost::variant
.将配置格式化为 JSON,并使用像 jsoncpp 这样的库怎么样?
例如,
您可以将其读入命名变量,甚至将其全部存储在 std::map 等中。后者意味着您可以添加选项,而无需更改和重新编译配置解析器。
How about formatting your configuration as JSON, and using a library like jsoncpp?
e.g.
You can then read it into named variables, or even store it all in a std::map, etc. The latter means you can add options without having to change and recompile your configuration parser.
我一直在寻找像 python 模块 ConfigParser 一样工作的东西,并发现了这个: https://github.com/jtilly/inih
I was looking for something that worked like the python module ConfigParser and found this: https://github.com/jtilly/inih
我最近搜索了我的项目的配置解析库,发现了这些库:
使用示例在源码包和这里
I've searched config parsing libraries for my project recently and found these libraries:
examples of using are in the source package and here
我将其他解决方案的一些内容合并为对我来说更直观且不易出错的解决方案。我使用公共
stp::map
来跟踪可能的配置 ID,并使用struct
来跟踪可能的值。就这样:}
I merged bits of the other solutions into something more intuitive and less error prone for me. I use a public
stp::map
to keep track of the possible config ids, and astruct
to keep track of the possible values. Here it goes:}
为什么不尝试一些简单且人类可读的东西,比如 JSON(或 XML)?
有许多用于 C++ 的 JSON(或 XML)的预制开源实现 - 我会使用其中之一。
如果你想要更多“二进制”的东西 - 尝试 BJSON 或 BSON :)
Why not trying something simple and human-readable, like JSON (or XML) ?
There are many pre-made open-source implementations of JSON (or XML) for C++ - I would use one of them.
And if you want something more "binary" - try BJSON or BSON :)
我正在寻找类似的简单 C++ 配置文件解析器,本教程网站 为我提供了一个基本但有效的解决方案。完成工作的灵魂是快速而肮脏的。
以下程序读取之前的配置文件:
I was searching for a similar simple C++ config file parser and this tutorial website provided me with a basic yet working solution. Its quick and dirty soultion to get the job done.
The following program reads the previous configuration file: