Hallo zusammen
Ich haben sehr einfachen xml Parser geschrieben, der noch nicht so funktioniert, wie er sollte.
Erklaerung: Der Parser durchlaeuft die Datei. Wenn er einen oeffnenden Tag ( ' < ' ) findet, legt er einen Stack an. Dann geht er weiter und speichert die weiteren Tags mit ihren jeweiligen Werten im Stack. Wenn ein schliessender Tag kommt ( ' /> ' ) werden alle Werte, die er bisher gespeichert hat, aus dem Stack genommen und zusammen gerechnet. Die Summe wird wieder auf den Stack gelegt und alle bisherigen Tags werden verworfen. So macht er weiter und addiert die neu gesammelten Werte wieder mit der vorhergehenden Summe und gibt am Schluss den Schlusswert (die Impedanz) zurueck.
Leider gibt das Programm jetzt immer nur 0.00 aus.
Ich habe im Programm auch Subtraktion, Multiplikation und Division implementiert, weil das Programm mehr tun sollte als nur addieren. Aber erst soll es ueberhaupt mal laufen, bis es die anderen Rechenoperationen anwenden kann.
Ich hoffe jemand sieht den Fehler und kann mir sagen, warum die Werte nicht addiert werden und das Programm immer nur Null als Resultat ausgibt, anstatt 11.
Mein Code:
Das xml-File:
Ich haben sehr einfachen xml Parser geschrieben, der noch nicht so funktioniert, wie er sollte.
Erklaerung: Der Parser durchlaeuft die Datei. Wenn er einen oeffnenden Tag ( ' < ' ) findet, legt er einen Stack an. Dann geht er weiter und speichert die weiteren Tags mit ihren jeweiligen Werten im Stack. Wenn ein schliessender Tag kommt ( ' /> ' ) werden alle Werte, die er bisher gespeichert hat, aus dem Stack genommen und zusammen gerechnet. Die Summe wird wieder auf den Stack gelegt und alle bisherigen Tags werden verworfen. So macht er weiter und addiert die neu gesammelten Werte wieder mit der vorhergehenden Summe und gibt am Schluss den Schlusswert (die Impedanz) zurueck.
Leider gibt das Programm jetzt immer nur 0.00 aus.
Ich habe im Programm auch Subtraktion, Multiplikation und Division implementiert, weil das Programm mehr tun sollte als nur addieren. Aber erst soll es ueberhaupt mal laufen, bis es die anderen Rechenoperationen anwenden kann.
Ich hoffe jemand sieht den Fehler und kann mir sagen, warum die Werte nicht addiert werden und das Programm immer nur Null als Resultat ausgibt, anstatt 11.
Mein Code:
Code:
#include <iostream>
#include <string>
#include <algorithm>
#include <fstream>
#include <stack>
#include <list>
#include <sstream>
using namespace std;
// string zu irgendeinem datentyp konvertieren
template <class T>
bool from_string(T& t, const string& s, ios_base& (*f)(ios_base&))
{
istringstream iss(s);
return !(iss >> f >> t).fail();
}
struct complex
{
float real;
float imag;
};
//addieren
complex addComplex(complex a, complex b)
{
complex res;
res.real=a.real+b.real;
res.imag=a.imag+b.imag;
return res;
}
//subtrahieren
complex subtractComplex(complex a, complex b)
{
complex res;
res.real=a.real-b.real;
res.imag=a.imag-b.imag;
return res;
}
//multiplizieren
complex multiplyComplex(complex a, complex b)
{
complex res;
res.real=a.real*b.real - a.imag*b.imag;
res.imag=a.imag*b.real + a.real*b.imag;
return res;
}
//dividieren
complex divideComplex(complex a, complex b)
{
complex res;
//{ac + bd}{c^2 + d^2}
res.real = (a.real*b.real + a.imag*b.imag)*(b.real*b.real + b.imag*b.imag);
res.imag = 1/((a.imag*b.real - a.real*b.imag)*(b.real*b.real + b.imag*b.imag));
return res;
}
//komplex in string umwandeln in der form (real,imag)
string complexToString(complex c)
{
string real, imag;
string rv;
//float val =3.456;
stringstream ss (stringstream::in | stringstream::out);
rv = "(";
ss << c.real;
rv += ss.str();
rv += ",";
ss << c.imag;
rv += ss.str();
rv += ")";
ss << c.imag;
return rv;
}
complex stringToComplex(string s)
{
string real, imag;
complex rv;
real = s.substr(1, s.find(","));
imag = s.substr(s.find(","), s.find(")")-s.find(","));
from_string<float>(rv.real, real, std::dec);
from_string<float>(rv.imag, imag, std::dec);
return rv;
}
int main(int argc, char *argv[])
{
//char filename[128];
ifstream file;
string zeile;
stack<string> stack;
string test ("");
string value;
complex val1;
complex val2;
//complex retVal;
stringstream ss (stringstream::in | stringstream::out);
bool debug;
debug = false;
file.open("inputfile.dat"); //filename);
if (file.good())
{
// file geoeffnet
// An den Anfang der Datei springen
file.seekg(ios::beg);
while (! file.eof())
{
// Die Datei zeilenweise auslesen
getline(file, zeile);
// ParseLine: gehe Zeile Durch, wenn <, dann neues Zeichen, das auf den Stack muss, sonst wenn </
// haben wir ein Closing Tag
bool tag_opened = false;
bool quote_opened = false;
test = "";
complex oneConstant;
oneConstant.real = 1.0f;
oneConstant.imag = 0.0f;
for (int i = 0; i<zeile.length(); i++)
{
if (zeile[i]=='<')
{
tag_opened = true;
}
else if ((zeile[i]=='"') && (!quote_opened))
{
quote_opened = true;
}
else if ((tag_opened || quote_opened) && (!(zeile[i]=='"')) && (!(zeile[i]=='>')))
test += zeile[i];
else if ((quote_opened == true && zeile[i]=='"') || (tag_opened == true && zeile[i]=='>'))
{
tag_opened = false;
quote_opened = false;
if (debug)
if (!test.empty()) cout << test << endl;
if (test.compare("/resistance") == 0)
{
// Resistance: Z = R
if (debug)
cout << "Closing resistance found" << endl;
value = stack.top();
from_string<float>(val1.real, value, dec);
val1.imag = 0.0f;
// den wert vom stack nehmen
stack.pop();
// wert zurueck tun
stack.push(complexToString(val1));
}
else if (test.compare("/coil") == 0)
{
if (debug)
cout << "Closing coil found" << endl;
value = stack.top();
from_string<float>(val1.imag, value, std::dec);
val1.real = 0.0f;
// wert vom stack nehmen
stack.pop();
stack.push(complexToString(val1));
}
else if (test.compare("/condenser") == 0)
{
if (debug)
cout << "Closing condenser found" << endl;
value = stack.top();
// wert vom stack nehmen
stack.pop();
from_string<float>(val1.imag, value, dec);
val1.imag *= -1;
val1.real = 0.0f;
// den "<condenser>" tag entfernen
stack.pop();
stack.push(complexToString(val1));
}
else if (test.compare("/parallel") == 0)
{
// parallel: alle werte zusammen addieren bis zum schluss tag mit 1/wert
if (debug)
cout << "Closing parallel found" << endl;
while (!(stack.top().compare("parallel")))
{
val1 = stringToComplex(stack.top());
stack.pop();
val2 = stringToComplex(stack.top());
stack.pop();
stack.push(complexToString(addComplex(divideComplex(oneConstant, val1), divideComplex(oneConstant, val1))));
}
// start series tag entfernen
stack.pop();
}
else if (test.compare("/series") == 0)
{
// series: alle werte addieren
if (debug)
cout << "Closing series found" << endl;
while (!(stack.top().compare("series")))
{
val1 = stringToComplex(stack.top());
stack.pop();
val2 = stringToComplex(stack.top());
stack.pop();
stack.push(complexToString(addComplex(val1, val2)));
}
// start series tag entfernen
stack.pop();
}
else if (test.compare("/circuit") == 0)
{
if (debug)
cout << "Closing circuit found" << endl;
// resultat plotten
cout << "Impedance: " << stack.top() << endl;
}
else
{
stack.push (zeile);
}
test = "";
}
}
}
}
else
{
// Wenn die Datei nicht geoeffnet werden konnte
cout << "Datei nicht gefunden." << endl;
}
return 0;
}
Das xml-File:
Code:
<circuit>
<series>
<resistance>"5"</resistance>
<parallel>
<resistance>"2"</resistance
<series>
<resistance>"1"</resistance>
<coil>"1"</coil>
</series>
</parallel>
<condenser>"2"</condenser>
</series>
</circuit>