Forum Programmation.c parser un fichier de config

Posté par  (site web personnel) .
Étiquettes : aucune
0
7
nov.
2006
Salut à tous,

Après plusieurs années passées à développer du Java, je dois repasser au C.

Je souhaiterais que mes programmes utilisent des fichiers de config
"clé-valeur". Exemple :

# Mon fichier de config
cle1=valeur1
cle2=valeur2
cle3=valeur3
...

En Java, je pouvais faire :
properties.load(new FileInputStream("maconfig.properties"));

C'est un peu l'équivalent que je souhaiterais faire en C.
getopt le permet-il ? Existe-t-il une librairie le permettant ?

Merci d'avance.

Jean-Yves.
  • # T'as du bol

    Posté par  (site web personnel) . Évalué à 4.

    Je l'utilisais justement aujourd'hui...
    GKeyFile dans la glib le permet: http://developer.gnome.org/doc/API/2.0/glib/glib-Key-value-f(...)
    Lis la section "description".
    • [^] # Re: T'as du bol

      Posté par  (site web personnel) . Évalué à 2.

      Super.
      Merci bcp !!
      • [^] # Re: T'as du bol

        Posté par  . Évalué à 1.

        un commentaire éventuellement hors sujet.
        Je ne doute pas que le bout de glib fasse ça très bien, mais as-tu vraiment envie de te cogner une dépendance à la glib pour un pauvre parsing de fichier ?

        si tu fais une appli gnome, je retire ce que j'ai dit :-)
        • [^] # Re: T'as du bol

          Posté par  (site web personnel) . Évalué à 4.

          Non, ce n'est pas du tout hors sujet :-)
          Effectivement, on peut se poser la question. C'est à lui de voir. Mais la Glib introduit beaucoup d'autres choses utiles (listes chainées, tableaux dynamiques, traitement de chaines de caractères, opérateurs d'allocation mémoire rapides - http://developer.gnome.org/doc/API/2.0/glib/glib-Memory-Slic(...) le tout portable sur un grand nombre de plateformes.
          Voir la liste complète: http://developer.gnome.org/doc/API/2.0/glib/index.html
          Résultat, si tu veux éviter des dépendances à plein de petites libs, c'est pas mal, et le code est plus uniforme et portable. L'API est très claire, donc facile à mémoriser, et orientée objet.

          De plus, glib n'est pas indissociable de gtk: une appli gtk utilisera la glib, mais l'inverse n'est pas forcément vrai. Je code actuellement une application qui dépend de glib, mais comme elle n'est pas graphique je n'utilise pas gtk. Par contre, je ne passe pas mon temps à réinventer la roue.
          • [^] # Re: T'as du bol

            Posté par  (site web personnel) . Évalué à 3.

            Ah, juste encore une chose: je vois en dessous libiniparser qui a l'air pas mal et sous license MIT (glib est LGPL). GKeyFile de la glib gère les listes de valeurs, du type:
            [section]
            ListeValeurs=toto;tata;titi

            Donc s'il préfère un truc léger et que le fait qu'il n'y ait pas de liste n'est pas bloquant, libiniparser a l'air cool, ou sinon je conseillerai glib, qui pourrait lui reservir par la suite.
    • [^] # Re: T'as du bol

      Posté par  (site web personnel) . Évalué à 0.

      ça va pas.

      - les properties java n'ont pas de notion de groupe ni de [localization]
      - dans les properties java on peut mettre des commentaires n'importe où
      - les properties java sont en ISO-8859-1 et peuvent contenir des caractères unicode sous forme \uXXXX
  • # libiniparser

    Posté par  . Évalué à 4.

  • # Solution JSON

    Posté par  (site web personnel) . Évalué à 2.

    Tu peux aussi te baser sur l'implémentation du parseur JSON en C. Avantage/inconvénient, ça permet de stocker des données plus complexes au niveau structure.

    http://json.org/
    http://oss.metaparadigm.com/json-c/

    Python 3 - Apprendre à programmer dans l'écosystème Python → https://www.dunod.com/EAN/9782100809141

  • # Solution C++

    Posté par  (site web personnel) . Évalué à 3.

    Si tu n'es pas complètement bloqué 'C', j'avais fait un tout petit outil qui me faisait ça tout seul en C++.

    http://www.limsi.fr/Individu/pointal/cpp.html#sources

    C'est même tellement court, que je te le poste ici:

    typedef map<string,string> ConfigMap;
    struct ConfigError
    {
    string message ;
    inline ConfigError(const string& msg)
    { message = msg ; } ;
    } ;
    class Config
    {
    private:
    ConfigMap m_pairs ;

    public:
    Config(const char* filepath) ;
    void get(const char* key, string& value, const char* defval=NULL) const ;
    } ;



    /*=============================================================================
    LECTURE DE CONFIGURATION
    =============================================================================*/
    Config::Config(const char* filepath)
    {
    string s ;
    ifstream configfile(filepath) ;
    while (configfile)
    {
    getline(configfile,s) ;
    if (not s.size() || s[0]=='#') continue ; // Ignore lignes vides et commentaires.
    int offset = s.find('=') ;
    string key(s.substr(0,offset)) ;
    string value(s.substr(offset+1,s.size())) ;
    m_pairs[key] = value ;
    }
    }
    void Config::get(const char* key, string& value, const char* defval) const
    {
    ConfigMap::const_iterator found = m_pairs.find(key) ;
    if (found == m_pairs.end()) // Retourne default.
    if (defval != NULL)
    value = defval ;
    else
    throw ConfigError((string("Unknown key: ")+key)) ;
    else
    value = (*found).second ;
    }



    Python 3 - Apprendre à programmer dans l'écosystème Python → https://www.dunod.com/EAN/9782100809141

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.