Auslesen von komplexen Zahlen aus einer Datei



  • Hallo,

    ich habde folgendes Problem. Es sollen komplexe Zahlen aus einer Datei ausgelesen werden, dafür habe ich eine Funktion geschrieben, die wie folgt aussieht.

    Die komplexen Zahlen haben immer die Form:
    -9.35124373769e-017-j1.53956708493e-017

    Problem ist, dass die Funktion nicht alle Werte ausliest. Momentan sollte sie eigentlich 74370 Werte auslesen und speichern, speichert jedoch nur 3721.

    Ich finde leider meinen Fehler nicht...

    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 i;
        while (f>>real>>plus>>j>>imag){
              i++;
            if(plus == '-'){
                 imag = imag *(-1);
            }
            complexNumbers.push_back(complex<double>(real,imag)); 	
        }
        cout<<endl<<i<<endl;
        return complexNumbers;
    }
    


  • 1. Wieso nimmst du C-Strings ?

    2.Ist das J beim Anfang der zweiten Beispiel-Komplexen nur ein Schreibfehler oder gewollt so ?

    3. Deine Kommentare sind ein wenig schlecht in Sachen Aufschlussreich. Was ist dein Tag ? Das 'j' ?

    4.Zeile 19 ist komisch. Dass müsste imag *= -1; heißen.

    5. edit: nein, falsch.

    6. Dein eigentliches Problem ist (glaube ich) zu lösen, in dem du die Anzahl der Werte die du lesen willst, erstmal im Vector reservierst.



  • i ist nicht initialisiert.



  • ]1. Wieso nimmst du C-Strings ?

    Wie sollte ich es denn anders machen? Sry, bin noch Anfänger...

    2.Ist das J beim Anfang der zweiten Beispiel-Komplexen nur ein Schreibfehler oder gewollt so ?

    Das "j" ist gewollt da und gibt an, dass der imaginäre Anteil folgt.

    3. Deine Kommentare sind ein wenig schlecht in Sachen Aufschlussreich. Was ist dein Tag ? Das 'j' ?

    Mein Tag ist irgendeine Zeile in der Datei in der steht <dep U_ME1.v ...>, ab dieser Zeile sollen alle Werte gelesen werden und in einen vector geschrieben werden bis die Zeile </dep> kommt.

    4.Zeile 19 ist komisch. Dass müsste imag *= -1; heißen.

    Ist es denn falsch so wie es ist? Dachte ich müsste wegen dem -1 klammern!

    6. Dein eigentliches Problem ist (glaube ich) zu lösen, in dem du die Anzahl der Werte die du lesen willst, erstmal im Vector reservierst.

    [/quote]

    Schwierig, da die Anzahl der Werte ja eigentlich zu Anfang nicht bekannt ist...



  • Javun schrieb:

    3. Deine Kommentare sind ein wenig schlecht in Sachen Aufschlussreich. Was ist dein Tag ? Das 'j' ?

    Mein Tag ist irgendeine Zeile in der Datei in der steht <dep U_ME1.v ...>, ab dieser Zeile sollen alle Werte gelesen werden und in einen vector geschrieben werden bis die Zeile </dep> kommt.

    Komisches Tag. Sicher, dass es so komplex sein muss ?

    Javun schrieb:

    4.Zeile 19 ist komisch. Dass müsste imag *= -1; heißen.

    Ist es denn falsch so wie es ist? Dachte ich müsste wegen dem -1 klammern!

    Gar nix ist "falsch". Es ist so einfach einfacher.

    Javun schrieb:

    6. Dein eigentliches Problem ist (glaube ich) zu lösen, in dem du die Anzahl der Werte die du lesen willst, erstmal im Vector reservierst.

    Schwierig, da die Anzahl der Werte ja eigentlich zu Anfang nicht bekannt ist...

    ...und trotzdem möglich, indem du einfach rechtzeitig reservierst, wenn es nötig wird.



  • 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-008
    

    Die 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.


Anmelden zum Antworten