Auslesen von komplexen Zahlen aus einer Datei
-
Ich habe jedoch dem Fehler in der Funktion gefunden bzw. ist es kein Fehler in der Funktion sondern mein Fehler.
In der Datei stehen sowohl komplexe Zahlen, als auch normale double Zahlen z.B.
+7.92957402371e-014-j9.72455418304e-011 +3.10400451986e-008Die Funktion muss also so umprogrammiert werden, dass sie mit beiden Werten zurecht kommt und egal welche Zahl kommt sie in eine complex Zahl umwandelt.
Mein Versuch die Funktion so umzuschreiben, scheiterte jedoch vergeblich. Kann mir jmd. vllt. einen Tipp geben?
vector<complex<double> > readComplexNumbers(const char* filename,const char* tag, const char* attributeName){ vector<complex<double> > complexNumbers; ifstream f(filename); //solange Zeilen ignorieren, bis der Tag gefunden wurde while(!isAttributeTag(f,tag,attributeName)){ f.ignore( numeric_limits< streamsize >::max(), '\n' ); } //die Zeile des Tags ebenso ignorieren f.ignore( numeric_limits< streamsize >::max(), '\n' ); //nun Werte lesen double real, imag; char plus, j, vorzeichen; for(int p=0; p<74370; p++){ if(f>>real>>plus>>j>>imag){ f>>real>>plus>>j>>imag; if(plus == '-'){ imag *= -1; } } if(f>>real){ f>>real; imag=0; } complexNumbers.push_back(complex<double>(real,imag)); } return complexNumbers; }
-
Übrigens komisch, dass du mit complexes und vectoren herumhantierst und kein std::string kennst.
Edit: Sicher, dass Zeile 16+17 korrekt sind ?
-
Ich würde dir ja zu boost::spirit raten, aber das wäre dir wohl fürs erste zu viel.
-
Hacker schrieb:
Übrigens komisch, dass du mit complexes und vectoren herumhantierst und kein std::string kennst.
Edit: Sicher, dass Zeile 16+17 korrekt sind ?
Ich habe es erstmal mit strings versucht und auch einen Thread dazu hier im Forum verfasst. Jedoch wurde mir dann schnell dazu geraten mit complex und vectoren zu arbeiten, da weitaus mehr als 1 Mio. Zeilen, also 1 Mio. Werte zu bearbeiten sind.
Ob Zeile 16+17 falsch sind weiß ich leider nicht, habe probiert Zeile 17 rauszunehmen, jedoch ist das Ergebnis auch falsch.
-
Und Z. 22+23 ?
Und kannst du mal erklären, inwiefern das Ergebniss falsch ist ?
-
Hacker schrieb:
Und Z. 22+23 ?
Und kannst du mal erklären, inwiefern das Ergebniss falsch ist ?
Ich habe es Mal mit folgendem Quellcode getestet. Das Ergebnis ist falsch, da jeder ausgelesene Wert gleich ist, als würde er die gleiche Zeile 74370 Mal auslesen.
Weiterhin müsste a+b = 74370 sein. a = 1 und b = 1. Also irgendetwas stimmt da nicht...
//ließt alle Werte nach <tag attributeName ....> vector<complex<double> > readComplexNumbers(const char* filename,const char* tag, const char* attributeName){ vector<complex<double> > complexNumbers; ifstream f(filename); //solange Zeilen ignorieren, bis der Tag gefunden wurde while(!isAttributeTag(f,tag,attributeName)){ f.ignore( numeric_limits< streamsize >::max(), '\n' ); } //die Zeile des Tags ebenso ignorieren f.ignore( numeric_limits< streamsize >::max(), '\n' ); //nun Werte lesen double real, imag; char plus, j, vorzeichen; int a = 0; int b = 0; for(int p=0; p<74370; p++){ if(f>>real>>plus>>j>>imag){ if(plus == '-'){ imag *= -1; } a++; } if(f>>real){ imag=0; b++; } // cout<<complex<double>(real,imag); complexNumbers.push_back(complex<double>(real,imag)); } cout<<endl<<a<<endl<<b<<endl; return complexNumbers; }
-
Hast du mal den Fehlerstatus des Streams überprüft?
-
314159265358979 schrieb:
Hast du mal den Fehlerstatus des Streams überprüft?
Ich weiß nicht wie man das macht oder was das sein soll.
Doch denke ich eher das der Fehler in der Ausleseroutine liegt.
z.B. ist der Code defintiv falsch, da das 2. if immer gegeben ist...
if(f>>real>>plus>>j>>imag){ if(plus == '-'){ imag *= -1; } a++; } if(f>>real){ imag=0; b++; }
-
Der Fehler besteht darin, dass deine Einleseroutine immer abwechselnd Zahlen mit und ohne Imaginärteil einliest.
-
Ich weiß nicht wie man das macht oder was das sein soll.
Du weisst nicht wie das geht ? RTFM ? Kom schon.
Es gibt verschiedene Member-Methoden (von ifstream) für Fehlerprüfung:
good() - true, wenn alles funktioniert hat. (Edit: Du kannst auch DeinIfstream statt DeinIfstream.good() schreiben.)
fail() - Gegenteil, gibt false zurück, wenn alles ordnungsgemäß ablief, bei Schreib- oder Lesefehlern aber true.
bad() - Wenn gravierende Fehler vorliegen, die den Stream komplett funktionsuntüchtig machen.Hast du schon exceptions gemacht ?
-
Das mit dem Fehlerstatus war Unfug, tut er ja schon mit if. Er liest einfach falsch ein.
-
314159265358979 schrieb:
Der Fehler besteht darin, dass deine Einleseroutine immer abwechselnd Zahlen mit und ohne Imaginärteil einliest.
Aber das soll ja Sinn und Zweck dieser Funktion sein. Wenn ich nur komplexe Zahlen hätte, dann würde die Funktion auch tadellos funktionieren.
Die Problemstellung ist ja gerade eine Funktion zu entwerfen, welche sowohl reale als auch komplexe Zahlen in einen complex vector schreibt.
-
Und wenn auf komplexe eine weitere komplexe folgt, krachts.
-
Probier mal mit einem else vor dem if in zeile 7 (dein letzter Code) aus.
Das dürfte das Problem beheben.
-
Hacker schrieb:
Probier mal mit einem else vor dem if in zeile 7 (dein letzter Code) aus.
Nöp.
-
314159265358979 schrieb:
Und wenn auf komplexe eine weitere komplexe folgt, krachts.
Und wieso? Bzw. wie ist denn dieses Problem zu beheben zu umgehen?
Wenn ich statt if(...), else hinschreibe ist das Ergebnis leider immer noch falsch.
vector<complex<double> > readComplexNumbers(const char* filename,const char* tag, const char* attributeName){ vector<complex<double> > complexNumbers(7770); ifstream f(filename); //solange Zeilen ignorieren, bis der Tag gefunden wurde while(!isAttributeTag(f,tag,attributeName)){ f.ignore( numeric_limits< streamsize >::max(), '\n' ); } //die Zeile des Tags ebenso ignorieren f.ignore( numeric_limits< streamsize >::max(), '\n' ); //nun Werte lesen double real, imag; char plus, j, vorzeichen; int a = 0; int b = 0; for(int p=0; p<7770; p++){ if(f>>real>>plus>>j>>imag){ if(plus == '-'){ imag *= -1; } a++; } else{ imag=0; b++; } // cout<<complex<double>(real,imag); complexNumbers[p]=complex<double>(real,imag); } cout<<endl<<a<<endl<<b<<endl; return complexNumbers; }
-
NAIN,
else if(f>>real){ imag=0; b++; }mit der Bedingung von vorher.
-
Denk doch mal nach. Was ist das nächste, wenn eine reele Zahl eingelesen wurde? Entweder ein Imaginärteil, oder eine weitere Zahl. (reel oder komplex) Du musst irgendwie erkennen, was gerade gelesen wird.
Hackers Vorschlag ist, wenn mich nicht gerade alles täuscht, falsch.
-
Hacker schrieb:
NAIN,
else if(f>>real){ imag=0; b++; }mit der Bedingung von vorher.
Funktioniert leider alles nicht. Wie gesagt ich habe bereits alles versucht.
Die Einleseroutine muss grundsätzlich falsch sein und ich weiß nicht warum?!
Denk doch mal nach. Was ist das nächste, wenn eine reele Zahl eingelesen wurde? Entweder ein Imaginärteil, oder eine weitere Zahl. (reel oder komplex) Du musst irgendwie erkennen, was gerade gelesen wird.
Hackers Vorschlag ist, wenn mich nicht gerade alles täuscht, falsch.Wenn eine reele Zahl eingelesen wurde, dann springt er doch in die nächste Zeile und schaut ist diese komplex oder reel usw. usw.
Es ist ja immer eine Zahl pro Zeile vorhanden (also entweder komplex oder reel).
-
Nein, er schaut eben nicht, ob. Er liest solange ein, bis es fehlschlägt. Das ist dann der Zeitpunkt, an dem eine zweite komplexe Zahl kommt. Dann machts kabumm.