Question

J'essaie d'analyser un fichier INI en utilisant C++.Avez-vous des conseils sur la meilleure façon d'y parvenir ?Dois-je utiliser les outils API Windows pour le traitement des fichiers INI (que je ne connais pas du tout), une solution open source ou tenter de l'analyser manuellement ?

Était-ce utile?

La solution

Vous pouvez utiliser les fonctions de l'API Windows, telles que GetPrivateProfileString() et GetPrivateProfileInt().

Autres conseils

Si vous avez besoin d'une solution multiplateforme, essayez celle de Boost Options du programme bibliothèque.

Je n'ai jamais analysé les fichiers ini, je ne peux donc pas être trop précis sur ce problème.
Mais j'ai un conseil :
Ne réinventez pas la roue tant qu'une roue existante répond à vos exigences

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

Bonne chance :)

j'utilise SimpleIni.C'est multiplateforme.

Si vous utilisez déjà Qt

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

Puis lisez une valeur

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

Il existe de nombreux autres convertisseurs qui convertissent vos valeurs INI à la fois en types standard et en types Qt.Voir la documentation Qt sur QSettings pour plus d'informations.

cette question est un peu ancienne, mais je publierai ma réponse.J'ai testé différentes classes INI (vous pouvez les voir sur mon site web) et j'utilise également simpleIni car je souhaite travailler avec des fichiers INI à la fois sur Windows et WinCE.GetPrivateProfileString() de Windows fonctionne uniquement avec le registre sur WinCE.

C'est très facile à lire avec simpleIni.Voici un exemple:

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

inih est un simple analyseur ini écrit en C, il est également livré avec un wrapper C++.Exemple d'utilisation :

#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";

L'auteur dispose également d'une liste des bibliothèques existantes ici.

As-tu essayé libconfig;syntaxe très proche de celle de JSON.Je le préfère aux fichiers de configuration XML.

Si vous êtes intéressé par la portabilité de la plateforme, vous pouvez également essayer Boost.PropertyTree.Il prend en charge ini comme format de persistance, bien que l'arborescence des propriétés ne puisse avoir qu'un seul niveau de profondeur.

À moins que vous n'envisagiez de rendre l'application multiplateforme, l'utilisation des appels de l'API Windows serait la meilleure solution.Ignorez simplement la note dans la documentation de l'API indiquant qu'elle est fournie uniquement pour la compatibilité des applications 16 bits.

Peut-être une réponse tardive..Mais, les options qui valent la peine d'être connues..Si vous avez besoin d'une solution multiplateforme, vous pouvez certainement essayer GLIB, c'est intéressant..(https://developer.gnome.org/glib/stable/glib-Key-value-file-parser.html)

Je sais que cette question est très ancienne, mais je l'ai posée parce que j'avais besoin de quelque chose de multiplateforme pour Linux, Win32...J'ai écrit la fonction ci-dessous, c'est une fonction unique qui peut analyser les fichiers INI, j'espère que d'autres la trouveront utile.

règles et mises en garde :buf à analyser doit être une chaîne terminée par NULL.Chargez votre fichier ini dans une chaîne de tableau de caractères et appelez cette fonction pour l'analyser.les noms de section doivent être entourés de crochets [], comme ceci [MySection], et les valeurs et les sections doivent également commencer sur une ligne sans espaces de début.Il analysera les fichiers avec des fins de ligne Windows ou Linux .Les commentaires doivent utiliser # ou // et commencer en haut du fichier, aucun commentaire ne doit être mélangé avec les données d'entrée INI.Les guillemets et les graduations sont supprimés aux deux extrémités de la chaîne de retour.Les espaces ne sont coupés que s’ils se trouvent en dehors du devis.Il n'est pas nécessaire que les chaînes contiennent des guillemets et les espaces sont coupés s'il manque des guillemets.Vous pouvez également extraire des nombres ou d'autres données, par exemple si vous avez un float, effectuez simplement un atof(ret) sur le tampon ret.

//  -----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
}

Comment utiliser...exemple....

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
}

J'ai fini par utiliser inipp qui n'est pas mentionné dans ce fil.

https://github.com/mcmtroffaes/inipp

Était une implémentation uniquement d'en-tête sous licence MIT qui était assez simple à ajouter à un projet et 4 lignes à utiliser.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top