繁体   English   中英

在 C/C++ 中解析配置文件

[英]Parse config file in C/C++

我是一个新手,正在寻找一种快速简便的方法来解析 C 或 C++ (wxWidgets) 中的文本文件

该文件看起来像这样(带有“子对象”的主类别),它将出现在列表框中

[CategoryA]

[SubCat]

    Str1 = Test 

    Str2 = Description  

[SubCat] [End]

[SubCat]

    Str1 = Othertest
...

[CategoryA] [End]

有什么建议么?

听起来你想解析一个非常接近 ini 文件的文件。

至少有一些 INI 解析器库:例如 minIniiniParserlibini

如果您使用流,那么为此编写自己的解析器应该相当容易。 您可以使用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++ 库。

见:http: //opensource.dshevchenko.biz/configurator

实现自己的解析器看起来比尝试调整您不熟悉的现有解析器更简单。

从您的示例来看,您的结构似乎是基于行的。 这使得解析变得容易。

将文件加载到树中,然后在必要时四处走动通常是有意义的。

仅在 Windows 上, GetPrivateProfileSection执行此操作。 它已被弃用,取而代之的是注册表,但它仍然存在并且仍然有效。

尝试制作一个简单的 XML 文件怎么样? 有很多库可以帮助您阅读它,另外还有很多其他程序/语言也可以阅读它。

如果您使用的是 wxWidgets 我会考虑wxFileConfig 我没有使用 wxWidgets,但该类似乎支持带有子类别的类别。

当您使用 GTK 时,您是幸运的。

您可以使用 Glib KeyFile save_to_fileload_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM