[英]Parse config file in C/C++
我是一个新手,正在寻找一种快速简便的方法来解析 C 或 C++ (wxWidgets) 中的文本文件
该文件看起来像这样(带有“子对象”的主类别),它将出现在列表框中
[CategoryA]
[SubCat]
Str1 = Test
Str2 = Description
[SubCat] [End]
[SubCat]
Str1 = Othertest
...
[CategoryA] [End]
有什么建议么?
如果您使用流,那么为此编写自己的解析器应该相当容易。 您可以使用std::ifstream
读取文件:
std::ifstream ifs("filename.ext");
if(!ifs.good()) throw my_exceptions("cannot open file");
read_file(ifs);
由于它看起来是面向行的,因此您将首先读取行,然后处理这些:
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");
}
对于实际的解析,您可以1)
首先查看第一个字符。 如果那是[
,从流中弹出它,并使用std::getline(is,identifier,']')
来读取 '[' 和 ']' 中的任何内容。 如果不是[
,则使用std::getline(is, key, '=')
读取键值对的左侧,然后使用std::getline(is, value)
读取右侧.
注意:不幸的是,流输入通常并不快如闪电。 (不一定要那样,但在实践中经常是这样。)然而,一旦你知道很少的模式来处理它的特性,它真的很容易做到,而且很容易做到正确(比如if(strm.good())
与if(strm)
,也不是if(strm.bad())
的对立面,还有一些你必须习惯的东西)。 对于像从磁盘读取 ini 文件这样对性能至关重要(har har!)的事情,在 1,000,000 个案例中的 999,999 个案例中,它应该足够快。
您可能想尝试Boost.Program_Options 。 但是它的格式略有不同。 更接近 INI 文件。 子类别是这样完成的:
[CategoryA]
Option = Data
[CategoryB.Subcategory1]
Option = Data
[CategoryB.Subcategory2]
Option = Data
它还具有其他一些功能,因此它实际上对 IMO 非常有用。
尝试配置器。 它是易于使用且灵活的 C++ 库,用于配置文件解析(从最简单的 INI 到具有任意嵌套和语义检查的复杂文件)。 仅标题和跨平台。 使用 Boost C++ 库。
实现自己的解析器看起来比尝试调整您不熟悉的现有解析器更简单。
从您的示例来看,您的结构似乎是基于行的。 这使得解析变得容易。
将文件加载到树中,然后在必要时四处走动通常是有意义的。
仅在 Windows 上, GetPrivateProfileSection
执行此操作。 它已被弃用,取而代之的是注册表,但它仍然存在并且仍然有效。
尝试制作一个简单的 XML 文件怎么样? 有很多库可以帮助您阅读它,另外还有很多其他程序/语言也可以阅读它。
如果您使用的是 wxWidgets 我会考虑wxFileConfig 。 我没有使用 wxWidgets,但该类似乎支持带有子类别的类别。
当您使用 GTK 时,您是幸运的。
您可以使用 Glib KeyFile save_to_file
和load_from_file
。
https://docs.gtk.org/glib/struct.KeyFile.html
或者在使用 Gtkmm (C++) 时。
请参阅: https ://developer-old.gnome.org/glibmm/stable/classGlib_1_1KeyFile.html
带有load_from_file
的 C++ 示例:
#include <glibmm.h>
#include <string>
Glib::KeyFile keyfile;
keyfile.load_from_file(file_path);
std::string path = keyfile.get_string("General", "Path");
bool is_enabled = keyfile.get_boolean("General", "IsEnabled");
保存就像调用save_to_file
一样简单:
Glib::KeyFile keyfile;
keyfile.set_string("General", "Path", path);
keyfile.set_boolean("General", "IsEnabled", is_enabled);
keyfile.save_to_file(file_path);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.