用 C/C++ 解析配置文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1417765/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Parse config file in C/C++
提问by Adam Badura
I'm a newbie looking for a fast and easy way to parse a text file in C or C++ (wxWidgets)
我是一个新手,正在寻找一种快速简便的方法来解析 C 或 C++ 中的文本文件(wxWidgets)
The file will look something like this (A main category with "sub-objects") which will appear in a list box
该文件看起来像这样(带有“子对象”的主类别),它将出现在列表框中
[CategoryA]
[SubCat]
Str1 = Test
Str2 = Description
[SubCat] [End]
[SubCat]
Str1 = Othertest
...
[CategoryA] [End]
Any suggestions?
有什么建议?
回答by Mark Rushakoff
回答by sbi
It should be fairly easy to write your own parser for this if you use streams. You can read a file using an std::ifstream
:
如果您使用流,为此编写自己的解析器应该相当容易。您可以使用以下命令读取文件std::ifstream
:
std::ifstream ifs("filename.ext");
if(!ifs.good()) throw my_exceptions("cannot open file");
read_file(ifs);
Since it seems line-oriented, you would then first read lines, and then process these:
由于它似乎是面向行的,因此您将首先读取行,然后处理这些:
void read_file(std::istream& is)
{
for(;;) {
std::string line;
std::getline(is, line);
if(!is) break;
std::istringstream iss(line);
// read from iss
}
if(!is.eof()) throw my_exceptions("error reading file");
}
For the actual parsing, you could 1)
first peek at the first character. If that's a [
, pop it from the stream, and use std::getline(is,identifier,']')
to read whatever is within '[' and ']'. If it isn't a [
, use std::getline(is, key, '=')
to read the left side of a key-value pair, and then std::getline(is, value)
to read the right side.
对于实际解析,您可以1)
先查看第一个字符。如果是[
,则将其从流中弹出,并用于std::getline(is,identifier,']')
读取 '[' 和 ']' 中的任何内容。如果不是 a [
,则使用std::getline(is, key, '=')
读取键值对的左侧,然后std::getline(is, value)
读取右侧。
Note: Stream input, unfortunately, is usually not exactly lightning fast. (This doesn't have to be that way, but in practice this often is.) However, it is really easy to do and it is fairly easy to do it right, once you know a very few patterns to work with its peculiarities (like if(strm.good())
not being the same as if(strm)
and not being the opposite of if(strm.bad())
and a few other things you'll have to get used to). For something as performance-critical (har har!) as reading an ini file from disk, it should be fast enough in 999,999 out of 1,000,000 cases.
注意:不幸的是,流输入通常不是闪电般的快。(这不一定是那样的,但在实践中经常是这样。)但是,一旦你知道很少的模式来处理它的特性(就像与您必须习惯的其他一些事情if(strm.good())
不同,if(strm)
而不是相反if(strm.bad())
)。对于像从磁盘读取 ini 文件这样对性能至关重要(har har!)的事情,在 1,000,000 个案例中的 999,999 个中它应该足够快。
回答by Adam Badura
You may want to try Boost.Program_Options. However it has slightly different formatting. More close to INI files. Subcategories are done like this:
您可能想尝试Boost.Program_Options。但是,它的格式略有不同。更接近于 INI 文件。子类别是这样完成的:
[CategoryA]
Option = Data
[CategoryB.Subcategory1]
Option = Data
[CategoryB.Subcategory2]
Option = Data
Also it has some other features so it is actually very useful IMO.
它还有一些其他功能,因此它实际上非常有用 IMO。
回答by Denis Shevchenko
Try Configurator. It's easy-to-use and flexible C++ library for configuration file parsing (from simplest INI to complex files with arbitrary nesting and semantic checking). Header-only and cross-platform. Uses Boost C++ libraries.
试试配置器。它是一个易于使用且灵活的 C++ 库,用于配置文件解析(从最简单的 INI 到具有任意嵌套和语义检查的复杂文件)。仅标题和跨平台。使用 Boost C++ 库。
回答by Will
It looks more straightforward to implement your own parser than to try to adapt an existing one you are unfamiliar with.
实现您自己的解析器看起来比尝试适应您不熟悉的现有解析器更直接。
Your structure seems - from your example - to be line-based. This makes parsing it easy.
从您的示例来看,您的结构似乎是基于行的。这使得解析变得容易。
It generally makes sense to load your file into a tree, and then walk around it as necessary.
将文件加载到树中,然后根据需要四处走动通常是有意义的。
回答by Emmanuel Caradec
On Windows only, GetPrivateProfileSection
does this. It's deprecated in favor of the registry but it's still here and it still works.
仅在 Windows 上,GetPrivateProfileSection
执行此操作。它已被弃用,有利于注册表,但它仍然存在并且仍然有效。
回答by kostia
How about trying to make a simple XML file? There are plenty of libraries that can help you read it, and the added bonus is that a lot of other programs/languages can read it too.
尝试制作一个简单的 XML 文件怎么样?有很多库可以帮助您阅读它,额外的好处是许多其他程序/语言也可以阅读它。
回答by larsmoa
If you're using wxWidgets I would consider wxFileConfig. I'm not using wxWidgets, but the class seems to support categories with sub-categories.
如果您使用 wxWidgets,我会考虑wxFileConfig。我没有使用 wxWidgets,但该类似乎支持带有子类别的类别。