webentwicklung-frage-antwort-db.com.de

Ini-Datei mit Boost analysieren

Ich habe eine INI-Datei, die einige Beispielwerte wie enthält:

[Section1]
Value1 = 10
Value2 = a_text_string

Ich versuche, diese Werte zu laden und in meiner Anwendung mit Boost auszudrucken, aber ich verstehe nicht, wie das in C++ gemacht wird.

Ich habe in diesem Forum gesucht, um einige Beispiele zu finden (ich habe immer C verwendet und bin daher in C++ nicht sehr gut), aber ich habe nur Beispiele gefunden, wie man Werte aus einer Datei auf einmal liest.

Ich muss nur einen einzelnen Wert laden, wenn ich möchte, wie string = Section1.Value2 weil ich nicht alle Werte lesen muss, sondern nur wenige.

Ich möchte einzelne Werte laden und in Variablen speichern, um sie zu verwenden, wenn ich in meiner Anwendung möchte.

Ist es möglich, dies mit Boost zu tun?

Im Moment benutze ich diesen 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;
   }

Dabei werden jedoch nur alle Werte in einer for -Schleife gelesen. im Gegenteil, ich möchte nur einzelne Werte lesen, wenn ich möchte, und ich muss keine Werte in die Datei einfügen, da sie bereits mit allen Werten geschrieben ist, die ich in meinem Programm benötige.

60
Marcus Barnet

Sie können Boost.PropertyTree auch zum Lesen von INI-Dateien verwenden:

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>

...

boost::property_tree::ptree pt;
boost::property_tree::ini_parser::read_ini("config.ini", pt);
std::cout << pt.get<std::string>("Section1.Value1") << std::endl;
std::cout << pt.get<std::string>("Section1.Value2") << std::endl;
134
Timo

Das Parsen von INI Dateien ist aufgrund ihrer einfachen Struktur einfach. Mit AX kann ich in wenigen Zeilen Abschnitte, Eigenschaften und Kommentare analysieren:

auto trailing_spaces = *space & endl;
auto section = '[' & r_alnumstr() & ']';
auto name = +(r_any() - '=' - endl - space);
auto value = '"' & *("\\\"" | r_any() - '"') & '"'
   | *(r_any() - trailing_spaces);
auto property = *space & name & *space & '=' & *space 
    & value & trailing_spaces;
auto comment = ';' & *(r_any() - endl) & endl;
auto ini_file = *comment & *(section & *(prop_line | comment)) & r_end();

Ein ausführlicheres Beispiel finden Sie in Reference.pdf

Das Lesen der gesamten Datei kann auf verschiedene Arten erfolgen. Zunächst erfordert der Parser für das Format INI) mindestens Forward-Iteratoren, sodass Sie keine Stream-Iteratoren verwenden können, da es sich um Eingabe-Iteratoren handelt. Sie können entweder eine separate Klasse für Streams mit erforderlichen Iteratoren erstellen (Ich habe in der Vergangenheit eine solche Klasse mit Gleitpuffer geschrieben.) Sie können eine speicherabgebildete Datei verwenden. Oder Sie können einen dynamischen Puffer verwenden, der aus dem Standard-Stream liest und dem Parser liefert, bis Sie die Werte gefunden haben. Wenn Sie nicht möchten Um einen echten Parser zu haben und sich nicht darum zu kümmern, ob die INI Dateistruktur korrekt ist oder nicht, können Sie einfach nach Ihren Tokens in der Datei suchen. Eingabe-Iteratoren würden dafür ausreichen.

Schließlich bin ich mir nicht sicher, ob das Vermeiden des Lesens der gesamten Datei irgendwelche Vorteile mit sich bringt. INI Dateien sind normalerweise ziemlich klein, und da die Festplatte und mehrere Puffersysteme sowieso einen oder mehrere Sektoren lesen würden (selbst wenn Sie nur ein Byte benötigen), bezweifle ich, dass es eine Leistung geben würde Verbesserung, indem versucht wird, die Datei teilweise zu lesen (insbesondere wiederholt), wahrscheinlich das Gegenteil.

3
Gene Bushuyev

Ich habe einen netten Artikel über INI-Parsing mit Boost-Methoden gelesen. Er heißt INI-Dateireader unter Verwendung der Spirit-Bibliothek von Silviu Simen .

Es ist ganz einfach.

2
mosg

Die Datei muss analysiert werden, was nacheinander erfolgen muss. Also würde ich einfach die ganze Datei lesen, alle Werte in einer Sammlung speichern (map oder unordered_map, wahrscheinlich entweder mit pair<section, key> als Schlüssel oder mit Karte von Karten) und holen Sie sie von dort bei Bedarf.

1
Jan Hudec