Frage

Ich bin versucht zu analysieren, eine INI-Datei mit C++.Irgendwelche Tipps, was ist der beste Weg, dies zu erreichen?Sollte ich das Windows-API-tools für die INI-Datei der Verarbeitung (was mir völlig unbekannt), eine open-source-Lösung oder versuchen zu analysieren Sie diese manuell?

War es hilfreich?

Lösung

Sie verwenden können die Windows-API-Funktionen, wie GetPrivateProfileString() und GetPrivateProfileInt().

Andere Tipps

Wenn Sie benötigen eine cross-Plattform-Lösung, versuchen Sie Steigern die Programm-Optionen Bibliothek.

Ich habe noch nie analysiert ini-Dateien, so kann ich nicht zu spezifisch auf dieses Problem.
Aber ich habe einen Tipp:
Das Rad nicht neu erfinden, solange eine bestehende zu Ihren Anforderungen entspricht

http://en.wikipedia.org/wiki/INI_file#Accessing_INI_files
http://sdl-cfg.sourceforge.net/
http://sourceforge.net/projects/libini/
http://www.codeproject.com/KB/files/config-file-parser.aspx

Gute Glück :)

Ich benutze SimpleIni.Es ist cross-Plattform.

Wenn Sie bereits eine Qt

QSettings my_settings("filename.ini", QSettings::IniFormat);

Lesen Sie dann den Wert

my_settings.value("GroupName/ValueName", <<DEFAULT_VAL>>).toInt()

Es gibt eine Reihe von anderen Konverter, konvertieren Sie Ihre INI-Werte in standard-und Qt-Typen.Siehe Qt-Dokumentation auf QSettings für mehr Informationen.

diese Frage ist ein bisschen alt, aber ich poste meine Antwort.Ich habe getestet, verschiedene INI-Klassen (Sie können finden Sie auf meiner website) und ich nutze auch simpleIni, weil ich wollen, um die Arbeit mit INI-Dateien unter windows und winCE.Fenster GetPrivateProfileString() funktioniert nur mit der Registrierung auf winCE.

Es ist sehr leicht zu Lesen mit simpleIni.Hier ist ein Beispiel:

#include "SimpleIni\SimpleIni.h"    
CSimpleIniA ini;
ini.SetUnicode();
ini.LoadFile(FileName);
const char * pVal = ini.GetValue(section, entry, DefaultStr);

inih ist eine einfache ini-parser in C geschrieben, es kommt mit einer C++ - wrapper zu.Beispiel Verwendung:

#include "INIReader.h"    

INIReader reader("test.ini");

std::cout << "version="
          << reader.GetInteger("protocol", "version", -1) << ", name="
          << reader.Get("user", "name", "UNKNOWN") << ", active="
          << reader.GetBoolean("user", "active", true) << "\n";

Der Autor hat auch eine Liste von bestehenden Bibliotheken hier.

Haben Sie versucht, libconfig;sehr JSON-ähnlichen syntax.Ich bevorzuge es über XML-Konfigurationsdateien.

Wenn Sie interessiert sind in der Plattform-Portabilität, Sie können auch versuchen Boost.PropertyTree.Es unterstützt die ini als persistancy format, obwohl die Eigenschaft Baum-mein 1 Ebene tief nur.

Es sei denn, Sie planen, die app, die cross-Plattform, mit der Windows-API-Aufrufe, wäre der beste Weg zu gehen.Ignorieren Sie den Hinweis in der API-Dokumentation über zur Verfügung gestellt nur für 16-bit-app-Kompatibilität.

Vielleicht eine späte Antwort..Aber lohnt sich zu wissen, Optionen..Wenn Sie benötigen eine cross-Plattform-Lösung , auf jeden Fall können Sie versuchen, GLIB,, die interessante..(https://developer.gnome.org/glib/stable/glib-Key-value-file-parser.html)

Ich weiß, diese Frage ist sehr alt, aber ich kam darauf, weil ich etwas brauchte cross-Plattform für linux, win32...Ich habe die Funktion unten, es ist eine einzelne Funktion, können analysieren INI Dateien hoffentlich andere finden es nützlich.

Regeln & Einschränkungen:buf analysiert werden müssen, eine mit NULL beendete Zeichenfolge.Laden Sie Ihre ini-Datei in ein char array, string und rufen Sie diese Funktion analysieren.Abschnitt müssen die Namen haben [] Klammern um Sie herum, wie dieser [MySection], auch Werte und Abschnitte müssen zunächst auf eine Zeile, ohne führende Leerzeichen.Es wird analysiert Dateien unter Windows \ \ \ n oder mit Linux zeilenendungen.Kommentare verwenden sollten, # oder // und beginnen Sie am Anfang der Datei keine Kommentare sollte gemischt werden mit INI-Eintrag-Daten.Zitate und Zecken sind getrimmt von beiden enden der Zeichenkette zurückgeben.Leerzeichen werden nur geschnitten, wenn Sie außerhalb der quote.Strings sind nicht erforderlich, um Anführungszeichen und Leerzeichen abgeschnitten werden, wenn die Anführungszeichen fehlen.Sie können auch extrahieren von zahlen oder anderen Daten, zum Beispiel, wenn Sie einen float-Sie brauchen nur atof(ret) auf die ret-Puffer.

//  -----note: no escape is nessesary for inner quotes or ticks-----
//  -----------------------------example----------------------------
//  [Entry2]
//  Alignment   = 1
//  LightLvl=128
//  Library     = 5555
//  StrValA =  Inner "quoted" or 'quoted' strings are ok to use
//  StrValB =  "This a "quoted" or 'quoted' String Value"
//  StrValC =  'This a "tick" or 'tick' String Value'
//  StrValD =  "Missing quote at end will still work
//  StrValE =  This is another "quote" example
//  StrValF =  "  Spaces inside the quote are preserved "
//  StrValG =  This works too and spaces are trimmed away
//  StrValH =
//  ----------------------------------------------------------------
//12oClocker super lean and mean INI file parser (with section support)
//set section to 0 to disable section support
//returns TRUE if we were able to extract a string into ret value
//NextSection is a char* pointer, will be set to zero if no next section is found
//will be set to pointer of next section if it was found.
//use it like this... char* NextSection = 0;  GrabIniValue(X,X,X,X,X,&NextSection);
//buf is data to parse, ret is the user supplied return buffer
BOOL GrabIniValue(char* buf, const char* section, const char* valname, char* ret, int retbuflen, char** NextSection)
{
    if(!buf){*ret=0; return FALSE;}

    char* s = buf; //search starts at "s" pointer
    char* e = 0;   //end of section pointer

    //find section
    if(section)
    {
        int L = strlen(section);
        SearchAgain1:
        s = strstr(s,section); if(!s){*ret=0; return FALSE;}    //find section
        if(s > buf && (*(s-1))!='\n'){s+=L; goto SearchAgain1;} //section must be at begining of a line!
        s+=L;                                                   //found section, skip past section name
        while(*s!='\n'){s++;} s++;                              //spin until next line, s is now begining of section data
        e = strstr(s,"\n[");                                    //find begining of next section or end of file
        if(e){*e=0;}                                            //if we found begining of next section, null the \n so we don't search past section
        if(NextSection)                                         //user passed in a NextSection pointer
        { if(e){*NextSection=(e+1);}else{*NextSection=0;} }     //set pointer to next section
    }

    //restore char at end of section, ret=empty_string, return FALSE
    #define RESTORE_E     if(e){*e='\n';}
    #define SAFE_RETURN   RESTORE_E;  (*ret)=0;  return FALSE

    //find valname
    int L = strlen(valname);
    SearchAgain2:
    s = strstr(s,valname); if(!s){SAFE_RETURN;}             //find valname
    if(s > buf && (*(s-1))!='\n'){s+=L; goto SearchAgain2;} //valname must be at begining of a line!
    s+=L;                                                   //found valname match, skip past it
    while(*s==' ' || *s == '\t'){s++;}                      //skip spaces and tabs
    if(!(*s)){SAFE_RETURN;}                                 //if NULL encounted do safe return
    if(*s != '='){goto SearchAgain2;}                       //no equal sign found after valname, search again
    s++;                                                    //skip past the equal sign
    while(*s==' '  || *s=='\t'){s++;}                       //skip spaces and tabs
    while(*s=='\"' || *s=='\''){s++;}                       //skip past quotes and ticks
    if(!(*s)){SAFE_RETURN;}                                 //if NULL encounted do safe return
    char* E = s;                                            //s is now the begining of the valname data
    while(*E!='\r' && *E!='\n' && *E!=0){E++;} E--;         //find end of line or end of string, then backup 1 char
    while(E > s && (*E==' ' || *E=='\t')){E--;}             //move backwards past spaces and tabs
    while(E > s && (*E=='\"' || *E=='\'')){E--;}            //move backwards past quotes and ticks
    L = E-s+1;                                              //length of string to extract NOT including NULL
    if(L<1 || L+1 > retbuflen){SAFE_RETURN;}                //empty string or buffer size too small
    strncpy(ret,s,L);                                       //copy the string
    ret[L]=0;                                               //null last char on return buffer
    RESTORE_E;
    return TRUE;

    #undef RESTORE_E
    #undef SAFE_RETURN
}

Die Verwendung...Beispiel....

char sFileData[] = "[MySection]\r\n"
"MyValue1 = 123\r\n"
"MyValue2 = 456\r\n"
"MyValue3 = 789\r\n"
"\r\n"
"[MySection]\r\n"
"MyValue1 = Hello1\r\n"
"MyValue2 = Hello2\r\n"
"MyValue3 = Hello3\r\n"
"\r\n";
char str[256];
char* sSec = sFileData;
char secName[] = "[MySection]"; //we support sections with same name
while(sSec)//while we have a valid sNextSec
{
    //print values of the sections
    char* next=0;//in case we dont have any sucessful grabs
    if(GrabIniValue(sSec,secName,"MyValue1",str,sizeof(str),&next)) { printf("MyValue1 = [%s]\n",str); }
    if(GrabIniValue(sSec,secName,"MyValue2",str,sizeof(str),0))     { printf("MyValue2 = [%s]\n",str); }
    if(GrabIniValue(sSec,secName,"MyValue3",str,sizeof(str),0))     { printf("MyValue3 = [%s]\n",str); }
    printf("\n");
    sSec = next; //parse next section, next will be null if no more sections to parse
}

Ich landete mit inipp, die nicht erwähnt in diesem thread.

https://github.com/mcmtroffaes/inipp

War ein MIT-lizenziert-header, nur die Umsetzung war einfach genug, um zu einem Projekt hinzufügen und 4 Zeilen zu verwenden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top