[Projektgestaltung] .ini Parser
-
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'
-
Auch auf die Gefahr hin, mich zu wiederholen: bitte verwende keinen Sprachen-Mischmasch.
(ansonsten solltest du mal etwas zusammenhängenderen Code vorführen, um das Problem zu erläutern - solche Probleme wie "Verwendung des undefinierten Typs ..." entstehen meist, weil nur eine Forward Deklaration dort steht, wo der Compiler eine vollständige Definition benötigt.
-
Sry. Ich dachte, das sei eher unproblematisch C und C++ zu vermischen.
parser.h
#ifndef INIPARSER_H #define INIPARSER_H 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; int getSection ( char *name ); int getTopic ( char *key, char *value ); public: CIniParser ( char *c_file ); ~CIniParser (); }; #endif
parser.cpp
#include <stdio.h> #include <malloc.h> #include "../tools/tools.h" // für sizeOfFile (); #include "parser.h" CIniParser::CIniParser ( char *c_file ) { root = NULL; actvs = NULL; actvkv = NULL; FILE *p_iniFile = NULL; // actvkv = new key_value; if ( ( p_iniFile = fopen ( c_file, "r" ) ) == NULL ) { this.~CIniParser (); } /* actvs = root; do { printf ( "%s\n", actvs->sectionname ); actvs = actvs->next; } while ( actvs != NULL ); getchar();*/ }; CIniParser::~CIniParser () { }; CIniParser::getSection ( char *name ) { if ( root == NULL ) { root = (section *)malloc ( sizeof( section ) ); actvs = root; root->first = NULL; root->last = NULL; root->next = NULL; root->prev = NULL; root->sectionname = name; return 0; } else { prevs = actvs; actvs = (section *)malloc ( sizeof( section ) ); prevs->next = actvs; actvs->first = NULL; actvs->last = NULL; actvs->next = NULL; actvs->prev = prevs; actvs->sectionname = name; return 0; } return 1; }; CIniParser::getTopic ( char *key, char *value ) { if ( root->first == NULL ) { actvkv = (key_value *)malloc ( sizeof( struct key_value ) ); return 0; } else { return 0; } return 1; };
-
Es ist vielleicht möglich, aber es ist verdammt schlechter Stil. Und mit C++ Mitteln kommst du idR wesentlich einfacher zum Ziel.
Ansonsten zu deinem Programm:
- in C++ ist es nicht mehr nötig "struct" vor deine Datentypen zu schreiben
- ein Destruktor sollte nur unter bestimmten Umständen von Hand aufgerufen werden (prinzipiell nur, wenn du dein Objekt mit placement new erzeugt hast). Wenn du es nicht schaffst, dein Objekt zu konstruieren, kannst du entweder eine Exception werfen oder dich in einen "hier geht nichts" Status setzen.
- wer kümmert sich eigentlich darum, deinen Speicher wieder freizugeben?
- und last, but not least: Wo genau tritt der Fehler auf?
-
Pyro Phoenix schrieb:
Sry. Ich dachte, das sei eher unproblematisch C und C++ zu vermischen.
die syntaxen beider sprachen ist sich sehr änhlich, aber damit hat sich's dann auch schon. mit mischen kommst du auf kurz oder lang in teufels küche.
-
CStoll schrieb:
- und last, but not least: Wo genau tritt der Fehler auf?
Zeile 76 (parser.cpp)
-
Ohohoho ...
Ihr habt nen Arschtitt bei mir gut ...
Ein typo in Linie 17 ( parser.h )
v anstatt y
-
warum tust du dir den malloc krempel an, wenn du sowieso nen c++ compiler verwenden musst?
-
Darum.
So:
getSection ( char *name ) { if ( root == NULL ) { root = (section *)malloc ( sizeof( section ) ); // Neues Sektions-Objekt bereitstellen. actvs = root; // Aktive Sektion = root root->first = NULL; root->last = NULL; root->next = NULL; root->prev = NULL; root->sectionname = name; // Name zuweisen. prevs = actvs; // Fertig. Vorherige Sektion = Aktive Sektion. return 0; } else { actvs = (section *)malloc ( sizeof( section ) ); // Neues Sektions-Objekt bereitstellen. prevs->next = actvs; // Neue Sektion mit der vorherigen Sektion verlinken. actvs->first = NULL; actvs->last = NULL; actvs->next = NULL; actvs->prev = prevs; // Vorherige Sektion in der neuen Sektion verlinken. actvs->sectionname = name; // Name zuweisen. prevs = actvs; // Fertig. Vorherige Sektion = aktive Sektion. return 0; } return 1; };
getTopic ( char *key, char *value ) { if ( actvs->first == NULL ) { actvkv = (key_value *)malloc ( sizeof( struct key_value ) ); // Neues Key-Value-Objekt bereitstellen. actvs->first = actvkv; // Erstes Key-Value-Objekt mit aktiver Sektion verlinken actvkv->member = actvs; // KV-Objekt ist Member der aktiven Sektion. actvkv->key = key; actvkv->value = value; actvkv->prev = NULL; actvkv->next = NULL; prevkv = actvkv; // Fertig. Vorheriges KV-Objekt = aktives KV-Objekt. return 0; } else { actvkv = (key_value *)malloc ( sizeof( struct key_value ) ); // Neues KV-Objekt bereitstellen. prevkv->next = actvkv; // Aktives KV-Objekt im vorherigen verlinken. actvkv->member = actvs; // KV-Objekt ist Member der aktiven Sektion. actvkv->key = key; actvkv->value = value; actvkv->prev = prevkv; // Vorheriges KV-Objekt im aktuellen verlinken. actvkv->next = NULL; prevkv = actvkv; // Fertig. Vorheriges KV-Objekt = aktives KV-Objekt. return 0; } return 1; };
Funktioniert 1A ... Jetzt wag ich mich mal an den Parser selbst.