[Projektgestaltung] .ini Parser



  • Also ich möchte nen Parser basteln, der vom Inhalt/Gestaltung der ini Datei unabhängig Parameter und Werte raussucht / zuordnet. Den ich also immer und überall
    und nicht nur für bestimmte Datenstrukturen verwenden kann.

    Ich hab nur keine Ahnung, wie ich das bewerkstelligen soll. 🙄



  • Moment mal, zurück auf Anfang: Eine INI-Datei hat eine feste Struktur (einzelne Sektionen, darin jeweils die Werte als "Name=Wert" aufeglistet. Und für die interne Verarbeitung solltest du diese Aufteilung als Grundlage verwenden, um möglichst flexibel auf die Daten zugreifen zu können.

    Nach außen (also an die Anwendung, die einen INI-Parser nutzen will) stellst du dann Funktionen zur Verfügung, um mit dem Sektions- und Variablennamen einen Wert auszulesen bzw. einzutragen. Was für Werte da letztendlich gebraucht werden, geht den Parser nichts mehr an (solange die Anwendung die Namen kennt).



  • Ja soweit passt das auch mit dem, was ich mir vorgestellt hatte.
    Aber eine 'feste Struktur' ?

    du meinst sowas wie:

    [Sektion 1]
    
    Wert1 = 1
    Wert2 = 4
    Wert3 = "Hallo"
    
    [Sektion 2]
    
    ...
    


  • Ja, genau das meinte ich - oder kennst du noch andere Formate für INI-Dateien? (und damit meine ich jetzt nicht XML und Konsorten)



  • Naja es gibt auch ini Dateien von diversen Spielen, die nicht so ein Muster vorweisen.
    Und die möchte ich ggf. auch mit meinem Parser bearbeiten können. ( Ist aber eher ein optionaler zusatz. erstmal das grundlegende machen )



  • Pyro Phoenix schrieb:

    Naja es gibt auch ini Dateien von diversen Spielen, die nicht so ein Muster vorweisen.
    Und die möchte ich ggf. auch mit meinem Parser bearbeiten können. ( Ist aber eher ein optionaler zusatz. erstmal das grundlegende machen )

    Es gibt aber ein Standard für INI Files: http://en.wikipedia.org/wiki/INI_file

    Wenn eine Datei diesem Muster nicht entspricht, dann ist es keine INI Datei (egal welche Endung die Datei hat).



  • Pyro Phoenix schrieb:

    Naja es gibt auch ini Dateien von diversen Spielen, die nicht so ein Muster vorweisen.
    Und die möchte ich ggf. auch mit meinem Parser bearbeiten können.

    möchtest du einen parser für standard-ini-dateien oder möchtest du einen pseudo-intelligenten parser schreiben, der verschiedene dateiformate automagisch unterstützt?

    mein rat: versuch dich erst mal an standard-init-dateien, bevor du dir größere ziele steckst.

    @net: dein dumpfes c++-gebashe wird langweilig, denk dir mal was neues aus.



  • du musst dir halt mal n paar ini files ansehen, oder wikipedia evtl.

    dann wirst du schon sehen, was bei allen ini files gleich ist.

    und das sind dann deine keywords für den parser.

    das sage ich aber, während ich selber keine ahnung hab wie ini files aussehen, bzw. ob sie überhaupt einigermassen einheitlich sind.

    aber genau diese einheitlichen begriffe, die immer wieder auftauchen, musst du vom parser scannen lassen.

    je nach dem, was du da lesen/schreiben willst, baust du dir ne struktur in deinem programm, die alle attribute hat, die du in einer ini-datei für dich sinnvoll hälst.



  • ininini schrieb:

    möchtest du einen parser für standard-ini-dateien oder möchtest du einen pseudo-intelligenten parser schreiben, der verschiedene dateiformate automagisch unterstützt?

    mein rat: versuch dich erst mal an standard-init-dateien, bevor du dir größere ziele steckst.

    Erstmal klein anfangen .. so hatte ich das geplant 😉

    hdi-loggedout schrieb:

    je nach dem, was du da lesen/schreiben willst, baust du dir ne struktur in deinem programm, die alle attribute hat, die du in einer ini-datei für dich sinnvoll hälst.

    Struktur? Bitte mal genauer erläutern.

    Also es gibt die

    ;Kommentar
    [Sektion]
    ;Kommentar
    Schlüssel=Wert
    

    Struktur.

    Also ich dachte mir, das man per Funktion ( sektion, schlüssel ) den
    entsprechenden Wert herausfinden kann.

    €dit:

    Laut Wikipedia:

    Bei dem Erstellen einer INI-Datei sind folgende Regeln zu beachten:

    • Jede Sektion darf nur einmal vorkommen.
    • Jeder Schlüssel darf nur einmal je Sektion vorkommen.
    • Kommentare werden mit einem ";" eingeleitet.
    • Auf Werte wird mittels Sektion und Schlüssel zugegriffen.
    • Kommentare dürfen nicht direkt hinter einem Schlüssel stehen.
    • Leerzeichen und Anführungszeichen werden von verschiedenen Programmen teilweise unterschiedlich behandelt.


  • Pyro Phoenix schrieb:

    Struktur? Bitte mal genauer erläutern.

    Also es gibt die

    ;Kommentar
    [Sektion]
    ;Kommentar
    Schlüssel=Wert
    

    Struktur.

    Also ich dachte mir, das man per Funktion ( sektion, schlüssel ) den
    entsprechenden Wert herausfinden kann.

    Ja, davon rede ich die ganze Zeit. Diesen Aufbau mußt du auf sinnvolle Art in den RAM übertragen (den gesamten Dateiinhalt binär in den Speicher zu schreiben, ist i.a. nicht sinnvoll).

    Eine Möglichkeit wäre es, Schlüssel-Einträge als Paar von Strings, Sektionen als Liste/Array/whatever von Schlüsseleinträgen (und evt. Kommentaren) und das gesamte INI-File als eine Liste/Array/whatever von Sektionen darzustellen.



  • Ich hab da ein kleines Problem:

    error C2440: '=' : 'struct CIniParser::section *' kann nicht in 'struct section *' konvertiert werden
    
    class CIniParser
    {
    private:
    
    	typedef struct section * s_node;
    	typedef struct key_value * kv_node;
    
    	typedef struct section
    	{
    		char	*sectionname;
    		s_node	next;
    		s_node	prev;
    		kv_node	first;
    		kv_node	last;
    	};
    
    	typedef struct kev_value
    	{
    		char	*key;
    		char	*value;
    		kv_node	next;
    		kv_node	prev;
    		s_node	member;
    	};
    
    	int p_buffer;
    
    	struct section *root;
    	struct section *actv;
    	struct section *prev;
    
    	int getSection ( char *name );
    	int getTopic ( char *key, char *value );
    
    public:
    
    	CIniParser  ( char *c_file );
    	~CIniParser ();
    
    };
    
    #endif
    

    Bei:

    prev->next = actv;
    

    Ich bin grad zu verpeilt um selber rauszufinden worans liegt ... 😡



  • "class", "private"? Bist du sicher, daß das immer noch C ist?

    Ansonsten: Was soll ein typedef bringen, wenn du dem Typ dabei keinen Namen gibst?



  • Ich habs in ne class gepackt. Alles in einer Datei war mir zu unübersichtlich.

    Naja hab das Problem jetz gelöst, indem ich die structs ausserhalb der Klasse
    definiere.



  • Pyro Phoenix schrieb:

    Ich habs in ne class gepackt. Alles in einer Datei war mir zu unübersichtlich.

    Darauf wollte ich gar nicht hinaus - ich wollte dich nur darauf hinweisen, daß "class" in C nicht existiert. Und wenn du sowieso schon C++ verwendest, dann gleich richtig 😉



  • Nächtes mal vielleicht ^^
    Wie gesagt, man soll mit den grundlagen anfangen.

    Hab jetz aber ein anderes Problem, dessen Lösung mir nicht bekannt ist.

    typedef struct key_value * kv_node;
    typedef struct section * s_node;
    
    struct section
    {
    	char	*sectionname;
    	s_node	next;
    	s_node	prev;
    	kv_node	first;
    	kv_node	last;
    };
    
    struct kev_value
    {
    	char	*key;
    	char	*value;
    	kv_node	next;
    	kv_node	prev;
    	s_node	member;
    };
    
    class CIniParser
    {
    private:
    
    	struct section *root;
    	struct section *actvs;
    	struct section *prevs;
    	struct key_value *actvkv;
    	struct key_value *prevkv;
    
    actvkv = new key_value;
    

    ergibt:

    error C2512: 'key_value' : Kein geeigneter Standardkonstruktor verfuegbar
    

    wobei jedoch:

    actvs = new section;
    

    keine probleme verursacht.



  • Pyro Phoenix schrieb:

    actvkv = new key_value;
    

    ergibt:

    error C2512: 'key_value' : Kein geeigneter Standardkonstruktor verfuegbar
    

    nimm 'malloc' für structs.
    🙂



  • Womit wir bei einer bunten Mischung aus C- und C++ Code wären - sowas ist weder besonders gut wartbar noch wirklich praktikabel. Entweder du nutzt reinen C++ Code oder reines C, aber bitte entscheide dich.



  • actvkv = (key_value *)malloc ( sizeof( key_value ) );
    

    ergibt:

    error C2027: Verwendung des undefinierten Typs "key_value"
    Siehe Deklaration von 'key_value'
    

    🙄



  • Du musst halt auch lesen, was CStoll zu deinen typedefs sagt. Probiers mit:

    actvkv = (struct key_value *)malloc ( sizeof( struct key_value ) );
    

    Allerdings ist die malloc-Vergipsung schon wieder so eine Hybridformulierung. Das einzige, was dafür spricht, ist daß es in C und C++ so läuft. In C99 sollte man das ohne Cast machen, in C++ mit static Casts. Kann dir egal sein, aber ich weise darauf hin.



  • Ergibt selbes Problem.

    error C2027: Verwendung des undefinierten Typs "key_value"
    Siehe Deklaration von 'key_value'
    

Anmelden zum Antworten