ufosworld
07-05-2007, 12:39
Folgendes Problem:
Ich habe eine Datei,
in ihr sind 0-x Funktionsnamen angegeben.
Zusätzlich zu den Funktionsnamen stehen bei jeder Funktion 0-xx Parameter dabei.
Nun sollen die Funktionsnamen in eine Verkettete Liste gespeichert werden.
solange bis keine Funktionsnamen mehr vorhanden sind.
Zu jedem Funktionsnamen sollen die kompletten Parameter als verkettete Liste angehängt werden..
Graphik 1 verdeutlicht das Prinzip
Mittlerweile speichert er auch schon die Funktionsnamen ab,
jedoch bei den Parametern habe ich anscheinend einen Fehler drin, diese speichert er auch ab, aber nicht zu jeder Funktion die entsprechenden Parameter, sondern komplett in einer verketteten Liste, was ja schwachsinn ist... da ich die Parameter so nie wieder einer entsprechenden Funktion zuordnen kann.
Die ganze Liste soll einmal eingelesen werden, nachträglich muss nichts mehr verändert werden. Sie dient dann nur dazu an die entsprechenden Funktionen mittels übergabe des Zeigers den Funktionsnamen und die Parameter zu liefern.
Hier mal die Datenfile.
<?xml version="1.0" encoding="UTF-8"?>
<SETTINGS>
<MODUL mod_id="0">
<MODULNAME mod_name="funktion1.so" />
<PARAMETER par="parameter1"/>
<PARAMETER par="dskjfsd2"/>
<PARAMETER par="33244"/>
<PARAMETER par="0"/>
</MODUL>
<MODUL mod_id="1">
<MODULNAME mod_name="funktion2.so" />
<PARAMETER par="test1_0"/>
<PARAMETER par="test1_1"/>
</MODUL>
<MODUL mod_id="2">
<MODULNAME mod_name="func3.so" />
<PARAMETER par=""/>
</MODUL>
....
<ENDE></ENDE>
</SETTINGS>
//------------------------------------------------------------------
Hier der Quellcode:
#include "tinyxml.h"
#include <list>
#include <string>
#include <map>
#include <iostream>
using namespace std;
struct TParaKnoten
{
string par; //Parameter
TParaKnoten *next; //Zeiger zum nächsten Parameter
};
TParaKnoten *ParAnk = 0;
TParaKnoten *ParOld;
struct TModulKnoten
{
int mod_id; // Mod_ID
string mod_name; // Mod_Name
TParaKnoten *para;
TModulKnoten *next; // Verknüpfung zum Nachfolger
};
TModulKnoten *Anker = 0; // Anfang der Liste
TModulKnoten *node, *old;
TModulKnoten *Start;
class SETTINGS
{
public:
string m_name;
SETTINGS() {}
void load(const char* pFilename);
};
void SETTINGS::load(const char* pFilename)
{
int MODID = 0;
int nummer=0;
int parnummer=1;
TiXmlDocument doc(pFilename);
if (!doc.LoadFile()) return;
TiXmlHandle hDoc(&doc);
TiXmlElement* pElem;
TiXmlHandle hRoot(0);
// block: name
{
pElem=hDoc.FirstChildElement().Element();
// should always have a valid root but handle gracefully if it does
if (!pElem) return;
m_name=pElem->Value();
// cout << pElem->Value()<< endl; // Ausgabe : SETTINGS
// save this for later
hRoot=TiXmlHandle(pElem);
}
// Modul-ID Modul-Name speichern in node->mod_id, node->mod_name //
pElem=hRoot.ChildElement(nummer).Element();
m_name = pElem->Value();
while(m_name != "ENDE")
{
if (m_name == "MODUL")
{
// cout << "Modul "<<nummer <<" gefunden"<<endl;
//Hier speichern der Werte Mod_id und Mod_Name in Liste
TModulKnoten *node = new TModulKnoten;
if(!node)
{
cerr << "Kein Speicher verfügbar!" << endl;
exit(1);
}
//Speichern der MOD_ID
pElem->QueryIntAttribute("mod_id",&node->mod_id);
//Setzen von pElem auf Tag MODULNAME
pElem= hRoot.ChildElement(nummer).FirstChild("MODULNAME").Element();
//Speichern des MOD_NAMEN
node->mod_name=pElem->Attribute("mod_name");
//Hier Speichern der Parameter //da is noch der Wurm drin...
pElem = hRoot.ChildElement(nummer).ChildElement(parnummer) .Element();
// if (pElem)
// {
m_name = pElem->Value();
while(m_name == "PARAMETER")
{
if (m_name == "PARAMETER")
{
TParaKnoten *para = new TParaKnoten;
if(!node)
{
cerr << "Kein Speicher verfügbar!" << endl;
exit(1);
}
// Speichern des Parameters in die Liste an Speicherstelle para->par
para->par = pElem->Attribute("par");
para->next = ParAnk; // Hänge bisherige Liste an
ParAnk = para; // Setze Anfangspunkt hierher
// cout <<"Attribute: " <<pElem->Attribute("par")<<endl; //Ausgabe: Attribut: gespeichertes Attribute
parnummer++;
pElem = hRoot.ChildElement(nummer).ChildElement(parnummer) .Element();
if (pElem)
{ // Wenn weiterer Parameter dann m_name = PARAMETER
m_name = pElem->Value();
// cout <<"m_name: "<< m_name<<endl; //Ausgabe: PARAMETER
}
else
{ //Falls anderer Value, dann Ende Parameter einlesen
break;
}
}
}
// }
// else
// {
// break;
// }
node->next = Anker; // Hänge die bisherige Liste an
Anker = node; // Setze den Anfangspunkt hierher
//Parameternummer auf Anfang stellen
parnummer=1;
//Weiter zum nächsten Modul
nummer++;
pElem=hRoot.ChildElement(nummer).Element();
m_name = pElem->Value();
}
if (m_name =="ENDE")
{
// cout << "ENDE gefunden"<<endl<<endl;
}
} //Ende While
} //Ende Settings
void delete_all()
{
//Hier liste wieder löschen damit keine Speicherlecks entstehen
while (Anker) // ungleich 0! Die Liste ist nicht leer!
{
cout << Anker->mod_id << endl;
cout << Anker->mod_name << endl;
while(ParAnk)
{
cout << ParAnk->par <<endl;
ParOld = ParAnk;
ParAnk = ParAnk->next;
delete ParOld;
ParOld = NULL;// Setze Zeiger auf Null
}
old = Anker; // Sichere zum späteren Löschen
Anker = Anker->next; // Ziehe nächstes Element nach vorn
delete old; // Lösche das ausgelesene Element
old = NULL; //setze Zeiger auf NULL
}
Anker = NULL; //setze Zeiger auf NULL
ParAnk = NULL; //setze Zeiger auf NULL
}
// ----------------------------------------------------------------------
// main()
// ----------------------------------------------------------------------
int main(int argc, char* argv[])
{
SETTINGS settings;
settings.load("test2.xml");
// cout << Start->mod_name << endl;
delete_all();
return 0;
}
//-------------------------------------------------------------------
Eventl kann mir ja jemand nen Tip geben, wie ich das so umbaue, das er mir für jede neue Parameterliste unter einer Funktion einen neue erstellt und nicht immer alles an eine Liste hinhängt....
die Ausgabe sieht nämlich dann so aus... und das ist ja falsch...
(auch im Debugger sieht man das er alle Parameter in eine Liste speichert ...)
(ausserdem speichert er mir die Liste verkehrt herum ab... kann man das auf die Schnelle ändern???..
- wie ich es verstanden habe, hängt er einen neuen Datensatz immer vorne an die Liste an.... ist das korrekt?
- feste Zeiger die auf Start und Ende zeigen wären auch von Vorteil.
2
func3.so
test1_1
test1_0
0
33244
dskjfsd2
parameter1
1
funktion2.so
0
funktion1.so
:(
danke schon mal UFO
Ich habe eine Datei,
in ihr sind 0-x Funktionsnamen angegeben.
Zusätzlich zu den Funktionsnamen stehen bei jeder Funktion 0-xx Parameter dabei.
Nun sollen die Funktionsnamen in eine Verkettete Liste gespeichert werden.
solange bis keine Funktionsnamen mehr vorhanden sind.
Zu jedem Funktionsnamen sollen die kompletten Parameter als verkettete Liste angehängt werden..
Graphik 1 verdeutlicht das Prinzip
Mittlerweile speichert er auch schon die Funktionsnamen ab,
jedoch bei den Parametern habe ich anscheinend einen Fehler drin, diese speichert er auch ab, aber nicht zu jeder Funktion die entsprechenden Parameter, sondern komplett in einer verketteten Liste, was ja schwachsinn ist... da ich die Parameter so nie wieder einer entsprechenden Funktion zuordnen kann.
Die ganze Liste soll einmal eingelesen werden, nachträglich muss nichts mehr verändert werden. Sie dient dann nur dazu an die entsprechenden Funktionen mittels übergabe des Zeigers den Funktionsnamen und die Parameter zu liefern.
Hier mal die Datenfile.
<?xml version="1.0" encoding="UTF-8"?>
<SETTINGS>
<MODUL mod_id="0">
<MODULNAME mod_name="funktion1.so" />
<PARAMETER par="parameter1"/>
<PARAMETER par="dskjfsd2"/>
<PARAMETER par="33244"/>
<PARAMETER par="0"/>
</MODUL>
<MODUL mod_id="1">
<MODULNAME mod_name="funktion2.so" />
<PARAMETER par="test1_0"/>
<PARAMETER par="test1_1"/>
</MODUL>
<MODUL mod_id="2">
<MODULNAME mod_name="func3.so" />
<PARAMETER par=""/>
</MODUL>
....
<ENDE></ENDE>
</SETTINGS>
//------------------------------------------------------------------
Hier der Quellcode:
#include "tinyxml.h"
#include <list>
#include <string>
#include <map>
#include <iostream>
using namespace std;
struct TParaKnoten
{
string par; //Parameter
TParaKnoten *next; //Zeiger zum nächsten Parameter
};
TParaKnoten *ParAnk = 0;
TParaKnoten *ParOld;
struct TModulKnoten
{
int mod_id; // Mod_ID
string mod_name; // Mod_Name
TParaKnoten *para;
TModulKnoten *next; // Verknüpfung zum Nachfolger
};
TModulKnoten *Anker = 0; // Anfang der Liste
TModulKnoten *node, *old;
TModulKnoten *Start;
class SETTINGS
{
public:
string m_name;
SETTINGS() {}
void load(const char* pFilename);
};
void SETTINGS::load(const char* pFilename)
{
int MODID = 0;
int nummer=0;
int parnummer=1;
TiXmlDocument doc(pFilename);
if (!doc.LoadFile()) return;
TiXmlHandle hDoc(&doc);
TiXmlElement* pElem;
TiXmlHandle hRoot(0);
// block: name
{
pElem=hDoc.FirstChildElement().Element();
// should always have a valid root but handle gracefully if it does
if (!pElem) return;
m_name=pElem->Value();
// cout << pElem->Value()<< endl; // Ausgabe : SETTINGS
// save this for later
hRoot=TiXmlHandle(pElem);
}
// Modul-ID Modul-Name speichern in node->mod_id, node->mod_name //
pElem=hRoot.ChildElement(nummer).Element();
m_name = pElem->Value();
while(m_name != "ENDE")
{
if (m_name == "MODUL")
{
// cout << "Modul "<<nummer <<" gefunden"<<endl;
//Hier speichern der Werte Mod_id und Mod_Name in Liste
TModulKnoten *node = new TModulKnoten;
if(!node)
{
cerr << "Kein Speicher verfügbar!" << endl;
exit(1);
}
//Speichern der MOD_ID
pElem->QueryIntAttribute("mod_id",&node->mod_id);
//Setzen von pElem auf Tag MODULNAME
pElem= hRoot.ChildElement(nummer).FirstChild("MODULNAME").Element();
//Speichern des MOD_NAMEN
node->mod_name=pElem->Attribute("mod_name");
//Hier Speichern der Parameter //da is noch der Wurm drin...
pElem = hRoot.ChildElement(nummer).ChildElement(parnummer) .Element();
// if (pElem)
// {
m_name = pElem->Value();
while(m_name == "PARAMETER")
{
if (m_name == "PARAMETER")
{
TParaKnoten *para = new TParaKnoten;
if(!node)
{
cerr << "Kein Speicher verfügbar!" << endl;
exit(1);
}
// Speichern des Parameters in die Liste an Speicherstelle para->par
para->par = pElem->Attribute("par");
para->next = ParAnk; // Hänge bisherige Liste an
ParAnk = para; // Setze Anfangspunkt hierher
// cout <<"Attribute: " <<pElem->Attribute("par")<<endl; //Ausgabe: Attribut: gespeichertes Attribute
parnummer++;
pElem = hRoot.ChildElement(nummer).ChildElement(parnummer) .Element();
if (pElem)
{ // Wenn weiterer Parameter dann m_name = PARAMETER
m_name = pElem->Value();
// cout <<"m_name: "<< m_name<<endl; //Ausgabe: PARAMETER
}
else
{ //Falls anderer Value, dann Ende Parameter einlesen
break;
}
}
}
// }
// else
// {
// break;
// }
node->next = Anker; // Hänge die bisherige Liste an
Anker = node; // Setze den Anfangspunkt hierher
//Parameternummer auf Anfang stellen
parnummer=1;
//Weiter zum nächsten Modul
nummer++;
pElem=hRoot.ChildElement(nummer).Element();
m_name = pElem->Value();
}
if (m_name =="ENDE")
{
// cout << "ENDE gefunden"<<endl<<endl;
}
} //Ende While
} //Ende Settings
void delete_all()
{
//Hier liste wieder löschen damit keine Speicherlecks entstehen
while (Anker) // ungleich 0! Die Liste ist nicht leer!
{
cout << Anker->mod_id << endl;
cout << Anker->mod_name << endl;
while(ParAnk)
{
cout << ParAnk->par <<endl;
ParOld = ParAnk;
ParAnk = ParAnk->next;
delete ParOld;
ParOld = NULL;// Setze Zeiger auf Null
}
old = Anker; // Sichere zum späteren Löschen
Anker = Anker->next; // Ziehe nächstes Element nach vorn
delete old; // Lösche das ausgelesene Element
old = NULL; //setze Zeiger auf NULL
}
Anker = NULL; //setze Zeiger auf NULL
ParAnk = NULL; //setze Zeiger auf NULL
}
// ----------------------------------------------------------------------
// main()
// ----------------------------------------------------------------------
int main(int argc, char* argv[])
{
SETTINGS settings;
settings.load("test2.xml");
// cout << Start->mod_name << endl;
delete_all();
return 0;
}
//-------------------------------------------------------------------
Eventl kann mir ja jemand nen Tip geben, wie ich das so umbaue, das er mir für jede neue Parameterliste unter einer Funktion einen neue erstellt und nicht immer alles an eine Liste hinhängt....
die Ausgabe sieht nämlich dann so aus... und das ist ja falsch...
(auch im Debugger sieht man das er alle Parameter in eine Liste speichert ...)
(ausserdem speichert er mir die Liste verkehrt herum ab... kann man das auf die Schnelle ändern???..
- wie ich es verstanden habe, hängt er einen neuen Datensatz immer vorne an die Liste an.... ist das korrekt?
- feste Zeiger die auf Start und Ende zeigen wären auch von Vorteil.
2
func3.so
test1_1
test1_0
0
33244
dskjfsd2
parameter1
1
funktion2.so
0
funktion1.so
:(
danke schon mal UFO