Auslesen von komplexen Zahlen aus einer Datei
-
Die Unterscheidung anhand der magischen Zahl 22 ist total willkürlich und wird dir oder jemand anderem in Zukunft noch Probleme machen. Warum unterscheidest du nicht anhand eines eindeutigen Kriteriums, z.B. ob ein 'j' drin vorkommt oder nicht?
-
SeppJ schrieb:
Die Unterscheidung anhand der magischen Zahl 22 ist total willkürlich und wird dir oder jemand anderem in Zukunft noch Probleme machen. Warum unterscheidest du nicht anhand eines eindeutigen Kriteriums, z.B. ob ein 'j' drin vorkommt oder nicht?
Oder ob nach
ss>>real>>plus>>j>>imag;
in j ein 'j' steht, anderenfalls plus, j und imag nicht verwendet werden.
-
SeppJ schrieb:
Die Unterscheidung anhand der magischen Zahl 22 ist total willkürlich und wird dir oder jemand anderem in Zukunft noch Probleme machen. Warum unterscheidest du nicht anhand eines eindeutigen Kriteriums, z.B. ob ein 'j' drin vorkommt oder nicht?
Also ich versteh schon worauf Du hinaus willst, aber das Programm welches ich schreibe ist ein reines Auswertunsprogramm für das Programm Qucs, da dieses leider keine Export Funktion bietet.
Die Zahlen haben daher immer den gleichen Aufbau bzw. die gleiche Länge. Hier Mal einen Ausschnitt als Beispiel:
+2.94796701276e-013+j1.10171292085e-012 +0.00000000000e+000 +0.00000000000e+000+j2.52435489671e-017 +8.45882878540e-014+j3.16122973146e-013Da die Zahl nicht größer sein kann als 22 wenn sie reel ist und größer als 22 sein muss wenn sie komplex ist, ist das doch ein eindeutiges Kriterium oder etwa nicht?
Oder ob nach
ss>>real>>plus>>j>>imag;
in j ein 'j' steht, anderenfalls plus, j und imag nicht verwendet werden.Das müsste natürlich auch funktionieren.
-
Kannst du das 'j' nicht weglassen und prüfen, ob das Zeichen (eigentlich 'j') ein '\n' (Zeilenumbruch) ist oder nicht ?
-
Hacker schrieb:
Kannst du das 'j' nicht weglassen und prüfen, ob das Zeichen (eigentlich 'j') ein '\n' (Zeilenumbruch) ist oder nicht ?
Theoretisch gesehen bestimmt, aber wie sieht das praktisch aus?!
Wenn ich stringstream ss>>double xyz mache, dann ist die Zahl ja weg. Also müsste ich jetzt das aktuelle oder das nächste Zeichen überprüfen? Und wie?
Funktionieren tut es ja bereits, ist nur eine Frage aus Interesse...Ich denke auch da wäre der Vorschlag von volkard besser.
-
Javun schrieb:
Funktionieren tut es ja bereits, ist nur eine Frage aus Interesse...Ich denke auch da wäre der Vorschlag von volkard besser.
Ich fürchte, mein Vorschlag ist viel schlechter.
Weil er nur nach "irgend einem" Fehler prüft.
1.245345353e07-j1.5fehler456
würde er als korrekte reelle Zahl 1.24e7 lesen.
Eigentlich sollte man auch versuchen, daß wenn man schon so ein genau gegebenes Format hat, möglichst viele Formatfehler aufgedeckt werden.
Also eigentlich entweder vorher die ganze Zeile nach dem j scannen, oder die Zeile Stückchenweise lesen und ein paar mehr ifs benutzen.
-
Werner Salomon: Wieder einmal ein sehr guter Beitrag von dir, der zu schade ist, um in der Versenkung zu verschwinden. Was hälst du davon, deine Lektionen als Artikel zu veröffentlichen? Wenn du willst, kann ich dir die Arbeit auch abnehmen.
-
Werner Salomon:
Mir kam da eine komische Idee. Also klar, erst eine ganze Zeile schnell zu lesen, sie in einen string zu kopieren, den in einen stringstream zu kopieren und dann nochmal zu lesen, das hat unnötige Kopierkosten.
Aber es ist oft so einfach...
Anfänger und ich mögen das.Könnte man statt
for(int p=0; p<21525; p++){ getline(f, s); istringstream ss(s); //parsen von ss }sowas wie
for(int p=0; p<21525; p++){ igetline_proxy ss(f); //parsen von ss, ganz unverändert }machen, wobei ss keine Kopie der Daten haben muß, sondern nur weiterleitet auf den ehrlichen streambuffer des files?
este Idee: Der Destruktor des igetline_proxy muß den eigentlichen istream noch lesen, bis er gegen eof oder einen Zeilenumbruch läuft, damit es sich so anfühlt, als hätte man vorher die ganze Zeile gelesen.
-
Oder man nimmt einfach meine Lösung. Die ist super kurz. Und noch viel superer einfach!

-
314159265358979 schrieb:
Oder man nimmt einfach meine Lösung. Die ist super kurz. Und noch viel superer einfach!

Ein Lob an die transzendente Zahl.
-
314159265358979 schrieb:
Oder man nimmt einfach meine Lösung. Die ist super kurz. Und noch viel superer einfach!

Welche genau?
-
314159265358979 schrieb:
template <typename Iter> std::complex<double> parse_complex(Iter begin, Iter end) { using namespace boost::spirit::qi; using boost::phoenix::ref; double real, imag = 0; char sign; if(!phrase_parse(begin, end, double_[ref(real) = _1] >> -((char_('+') | char_('-'))[ref(sign) = _1] >> 'j' >> double_[ref(imag) = _1]), ascii::space) || begin != end) throw parse_error("parse error here: " + std::string(begin, end)); return std::complex<double>(real, sign == '-' ? -imag : imag); }Um eine Lösungsmöglichkeit zu posten.
Die hier.

-
Fehlt nur noch ein "Ich bin es".
-
314159265358979 schrieb:
...
Ach, nö.
-
Findet aber alle Fehler im Format :p
(Zugegebenermaßen aber kein ernsthafter Lösungsvorschlag. Wollte nur eine möglichst kurze Lösung hinbekommen.)
-
Du wolltest also einfach allen Anwesenden (Mitlesenden?) demonstrieren, dass du es einfach übermäßigst draufhast.
Etwas anderes war ja kaum zu erwarten
-
mh. schrieb:
Du wolltest also einfach allen Anwesenden (Mitlesenden?) demonstrieren, dass du es einfach übermäßigst draufhast.
Etwas anderes war ja kaum zu erwarten

@Pi, wenn du cool sein willst, bist du hier falsch.
-
volkard schrieb:
Also klar, erst eine ganze Zeile schnell zu lesen, sie in einen string zu kopieren, den in einen stringstream zu kopieren und dann nochmal zu lesen, das hat unnötige Kopierkosten.
Aber es ist oft so einfach...
Anfänger und ich mögen das... kommt mir manchmal vor, wie die dunkle Seite der Macht - so schön verführerisch
(s. auch unten)volkard schrieb:
Könnte man statt
for(int p=0; p<21525; p++){ getline(f, s); istringstream ss(s); //parsen von ss }sowas wie
for(int p=0; p<21525; p++){ igetline_proxy ss(f); //parsen von ss, ganz unverändert }machen, wobei ss keine Kopie der Daten haben muß, sondern nur weiterleitet auf den ehrlichen streambuffer des files?
este Idee: Der Destruktor des igetline_proxy muß den eigentlichen istream noch lesen, bis er gegen eof oder einen Zeilenumbruch läuft, damit es sich so anfühlt, als hätte man vorher die ganze Zeile gelesen.
Ja .. die Idee ist gar nicht so neu. Wobei gar nicht der Stream ausgetauscht werden sollte. Dann hat man die selben Nachteile wie bei der getline-istringstream-Kombination. Der konkrete istream enthält alle Informationen (auch die nachträglich eingestellten); erzeugt man einen neuen, so gehen alle Nicht-Standard-Einstellungen verloren.
Was man machen könnte, wäre so einen getline_filter zwischen den Stream und den darunter liegenden streambuf zu schalten, aus dem man denn 'gegen EOF' lesen kann, was wesentlich einfacher ist, als 'gegen EOL' zu lesen. Dieser getline_filter könnte dann in seinem Destruktor alle Zeichen bis EOL des Original-streambuf überlesen - falls noch welche anstehen.
Ich hatte auch schon mal ein Beispiel dafür gepostet, finde es aber nicht mehr wieder.Gruß
Werner