fstream problem



  • out schrieb:

    Cevin19994 schrieb:

    achja was meinst du mit punk 3 (datentyp) ? also es ist ein ganz einfacher text oder was meinst du ?

    Naja, wenn in deiner Datei eine Kommazahl steht, soll sie höchst wahrscheinlich als double interpretiert werden. Wenn da eine Ganzzahl stellt, soll es wohl ein int sein.... Du willst ja was rechnen.

    unterschiedlich 🙂 in den dateien werden datum zeit(in stunden ) und an erstellten dateien wiedergegeben das sind manchmal ganze zahlen manchmal dezimalzahlen ...



  • Cevin19994 schrieb:

    Ok Ich möchte jetzt gerne meine frage umstellen 🙂
    ich möchte wissen wie man text inhalt von dateien liest nach bestimmten werten filtert , summiert und das ergebins in eine neue datei gespeichert wird ?
    Also ich weiß das ich die einzelnen funktion googlen kann aber nicht wie ich alles zusammen benutze ? wie kann man das hin kriegen ..

    Definiere Dir zunächst eine Struktur oder Klasse, die genau einen Datensatz von dem aufnehmen kann, was Dich interessiert. Soweit ich dass Deinen bisherigen Beiträgen entnehmen kann sind das das Datum und die Werte hours_worked und filescreated . Letztere sollen auch addiert werden. Also müsste die Struktur vielleicht so aussehen:

    #include <string>
    
    struct MD
    {
        std::string datum; // der Einfachheit halter als String definiert
        double hours_worked;
        double filescreated;
    };
    

    Zweiter Schritt ist die Implementierung einer Funktion, die genau einen solchen Datensatz liest. Ich unterstelle mal, dass die Datei so aussieht, wie Du sie hier beschrieben hast.
    Dann wäre das so zu machen:

    #include <istream>
    #include <fstream>
    #include <limits> // numeric_limits
    #include <string>
    
    // struct Md (s.o.)
    
    namespace
    {
        const std::streamsize ALL = std::numeric_limits< std::streamsize >::max();
    };
    
    std::istream& operator>>( std::istream& in, MD& md )
    {
        in.ignore( ALL, '[' ) >> md.datum;
        std::string token;
        if( getline( in.ignore( ALL, '|' ), token, '=' ) )
        {
            md.hours_worked = 0.; // initialisieren, da nicht immer alle Member gelesen werden!
            md.filescreated = 0.;
            if( token == "hours_worked" )
                in >> md.hours_worked;
            else if( token == "filescreated" )
                in >> md.filescreated;
            else
                in.setstate( std::ios_base::failbit ); // Formatfehler!
        }
        return in;
    }
    

    Die Signatur in Zeile 13 nennt man einen Extraktor oder Streaming-Operator zum Einlesen. Das ermöglicht Dir später, ein Objekt der Struktur MD genau so wie z.B. einen int zu lesen. Beispiel:

    MD md;
        if( cin >> md ) {
            // Objekt md richtig gelesen.
    

    In Zeile 15 wird mit dem ignore( ALL, '[' ) alles bis zum '[' überlesen und die folgenden Zeichen bis zum Leerzeichen sind dann wohl das Datum. Dann wird nochmal alles überlesen bis zum '|' (Zeile 17) und dann mit getline der String bis zum '=' gelesen, um heraus zu bekommen, ob es sich um hours_worked oder filescreated handelt.

    Der Rest ist dann einfach

    //Vorspann s.o.
    
    int main()
    {
        using namespace std;
        ifstream fin("C:/Ruby193/1.txt");
        fin.imbue( locale( "german" ) );
        if( !fin.is_open() )
        {
            cerr << "Fehler beim Oeffnen der Datei" << endl;
            return -2;
        }
        for( MD md; fin >> md; )
        {
            // hier md auswerten
            ; // .. addieren
        }
        if( fin.eof() )
        {
            cout << "alles gelesen" << endl;
        }
        return 0;
    }
    

    Ganz wichtig ist noch, dass Du in Zeile 7 dem Stream mitteilst, dass die Fließkommazahlen in deutscher Schreibweise also mit ',' als Dezimaltrenner - gelesen werden sollen.

    Damit wäre das Einlesen schon erledigt. Zum addieren könntest Du Dir einen Operator bauen, der zwei MD-structs einfach addiert. Wie das geht ist im Cpp-Magazin beschrieben.

    Gruß
    Werner



  • Werner ? Danke schön das hilft mir 100 % weiter 🙂
    und vielen dank das du alles so großzügig beschrieben hast 🙂
    so ist der lern effeckt grüßer 🙂



  • Hmmm Werner ? ich habe jetzt ein problem
    nachdem mir im forum nicht ganz geholfen wird ausser @out er hat mich auf den richtigen weg gebracht habe ich mein alten code weggeschmissen und neu angefangen ... da ist dann fast das gleiche wie bei dir rausgekommen nur mit viel mehr fehlern 😃
    dank dir konnte ich jetzt meine fehler ausbügeln ... danke 🙂
    dann hab ich alles noch mam ausgeführt und bekam diesen fehler : cerr und cout damit hat er ein problem
    das konnte ich abr mit dem includen von iostream lösen 😛
    jetzt wenn ich alles ausführe spuckt mir die console aus das die anwendung ungewöhnlich beendet wird dann reagiert sie nicht mehr und windows erzwingt das schließen diese prozes

    was tun ? kann es sein das es daran liegt weil ich die md noch nicht auswerten lasse ? glaube ich nicht gruß cevin 🙂



  • Na komm, jetzt sei Mal nicht undankbar. Die Leute haben immerhin Mühe und Zeit investiert, auch wenn der Ton und die Antworten vielleicht nicht immer so waren, wie Du es Dir gewünscht hättest. Aber jeder hat eben auch seine Auffassung, was dem Lernenden weiterhilft, und viele haben da eben auch eine, die nicht Deinen Vorstellung entspricht, obwohl sie gut gemeint war.

    Zu Deinem Problem: Der Code sollte nicht sonderlich komplex sein, oder? Du könntest ihn posten.

    Besser: Debugge doch Mal durch (d.h. setz Haltepunkte, der Debugger hält das Programm dann bei der Ausführung automatisch an und Du kannst von dort aus schrittweise vorgehen), um festzustellen, in welcher Zeile er genau "ungewöhnlich beendet wird". Vielleicht findest Du den Fehler dann auch selbst.



  • Ich bin ja nicht undankbar und ich versteh auch das jeder seine andere art hat hilfe anzubieten 🙂



  • Cevin19994 schrieb:

    das konnte ich abr mit dem includen von iostream lösen 😛
    jetzt wenn ich alles ausführe spuckt mir die console aus das die anwendung ungewöhnlich beendet wird dann reagiert sie nicht mehr und windows erzwingt das schließen diese prozes.

    Zeig mal deinen kompletten Code, der kompilierbar ist, und der den Fehler reproduziert.



  • #include <iostream>
    #include <istream> 
    #include <fstream> 
    #include <limits>  
    #include <string>
    
    struct MD 
    { 
        std::string datum; 
        double hours_worked; 
        double filescreated; 
    };
    
    namespace 
    { 
        const std::streamsize ALL = std::numeric_limits< std::streamsize >::max(); 
    }; 
    
    std::istream& operator>>( std::istream& in, MD& md ) 
    { 
        in.ignore( ALL, '[' ) >> md.datum; 
        std::string token; 
        if( getline( in.ignore( ALL, '|' ), token, '=' ) ) 
        { 
            md.hours_worked = 0.;  
            md.filescreated = 0.; 
            if( token == "hours_worked" ) 
                in >> md.hours_worked; 
            else if( token == "filescreated" ) 
                in >> md.filescreated; 
            else 
                in.setstate( std::ios_base::failbit ); 
        } 
        return in; 
    }
    
    int main() 
    { 
        using namespace std; 
        ifstream fin("C:/Ruby193/m.md"); 
        fin.imbue( locale( "german" ) ); 
        if( !fin.is_open() ) 
        { 
            cerr << "Fehler beim Oeffnen der Datei" << endl; 
            return -2; 
        } 
        for( MD md; fin >> md; ) 
        { 
            // hier md auswerten 
            ; // .. addieren 
        } 
        if( fin.eof() ) 
        { 
           cout << "alles gelesen" << endl;
        } 
        return 0; 
    }
    

    das ist das was werner mir gezeigt hat 🙂



  • Die einzige Möglichkeit, wo eine Exception geworfen werden kann, ist in Zeile 42. Dein System kennt wahrscheinlich die Locale("german") nicht.
    Auf welcher Umgebung arbeitest Du (Betriebssystem, Compiler)?

    Um sicher zu gehen: kopieren die Zeile 42 hinter Zeile 47 und füge vorher und nachher noch eine Ausgabe ein - etwa:

    int main()
    {
        using namespace std;
        ifstream fin("C:/Ruby193/m.md");
        if( !fin.is_open() )
        {
            cerr << "Fehler beim Oeffnen der Datei" << endl;
            return -2;
        }
        cout << "Datei ist offen" << endl;
        fin.imbue( locale( "german" ) );
        cout << "locale 'german'" << endl;
        for( MD md; fin >> md; )
           // usw.
    

    .. und probier' es nochmal.

    Wenn ich richtig informiert bin, müsste es unter Linux

    fin.imbue( locale( "de_DE" ) );
    

    heißen



  • werner du hast recht 😃 ... die console zeigt an datei offen und danch sagt er mir wieder das die anwendung auf ungewöhnliche art beendet wird

    das heißt der fehler trit ab

    fin.imbue( locale( "german" ) );
    

    auf

    ich benutze windows 7 und def c++

    ich will noch mir etwas linux basierendes raufhauen wie ubuntu oder so
    und wegen def c++ .. ich habs mit vusual c++ versucht aber aus ein mir nicht klaren grund will er esnicht installieren ? 🙂



  • Ok - ich hoffe es ist schon die neue Version des Dev-C++ also Orwell Dev-C++.

    Dann versuche mal heraus zu bekommen, wie dort die deutsche locale heißt.

    Sonst kannst Du auch vor Dein main-Programm diese Facette schreiben:

    struct Komma : public std::numpunct< char >
    {
    protected:
        virtual char_type do_decimal_point() const
        {
            return ',';
        }
    };
    

    und die Zeile mit imbue ändern:

    // fin.imbue( locale( "german" ) ); // wirft Exception, falls 'german' unbekannt
        fin.imbue( locale( fin.getloc(), new Komma ) );
    

    Falls das auch nicht klappt, so wechsle die Entwicklungsumgebung.

    PS.: eine Bitte: registriere Dich, schaue Dir Deine Beiträge vor dem Posten mit dem 'Vorschau'-Button an und korrigiere die ganz groben Rechtschreib- und Grammatik-Fehler. Dann kannst Du auch mit mehr Feedback rechnen.



  • Danke hat wunderbar geklappt. 🙂
    Da ich wohl öfter in diesem Forum rumlaufen werde ist es wohl wirklich besser wenn
    ich mich registriere.
    Jetzt brauche ich wohl nur noch die Md's auswerten lassen, summieren und abspeichern in eine neue Datei.
    Das sollte es gewesen sein denke ich 🙂



  • #include <iostream>
    #include <istream> 
    #include <fstream> 
    #include <limits>  
    #include <string>
    
    struct MD 
    { 
        std::string datum; 
        double hours_worked; 
        double filescreated; 
    };
    
    namespace 
    { 
        const std::streamsize ALL = std::numeric_limits< std::streamsize >::max(); 
    }; 
    
    std::istream& operator>>( std::istream& in, MD& md ) 
    { 
        in.ignore( ALL, '[' ) >> md.datum; 
        std::string token; 
        if( getline( in.ignore( ALL, '|' ), token, '=' ) ) 
        { 
            md.hours_worked = 0.;  
            md.filescreated = 0.; 
            if( token == "hours_worked" ) 
                in >> md.hours_worked; 
            else if( token == "filescreated" ) 
                in >> md.filescreated; 
            else 
                in.setstate( std::ios_base::failbit ); 
        } 
        return in; 
    }
    struct Komma : public std::numpunct< char > 
    { 
    protected: 
        virtual char_type do_decimal_point() const 
        { 
            return ','; 
        } 
    };
    
    int main() 
    { 
        using namespace std; 
        ifstream fin("C:/Ruby193/ab.md"); 
       fin.imbue( locale( fin.getloc(), new Komma ) );
        if( !fin.is_open() ) 
        { 
            cerr << "Fehler beim Oeffnen der Datei" << endl; 
            return -2; 
        } 
    
        for( MD md; fin >> md; ) 
        {  // auswerten
           fin >> MD ;
             // .. summieren
        } 
        if( fin.eof() ) 
        { 
           cout << "alles gelesen" << endl;
        } 
    
       ofstream myFile;  
       myFile.open ("C:/Ruby193/value.csv");
    
       if (myFile)
       {
    
           myFile << fin ;
             // Dateien schliessen / ich weiß nicht ob dies überhaupt notwendig ist ? :)
          myFile.close();
    
       }  
        return 0; 
    }
    

    Hallo
    ich bin's nochmal wieder 🙂
    Ich habe wieder ein Problem.
    unter mein Kommentar //auswerten bin ich gerade etwas planlos:/
    hier wird doch schon mit dem operator >> ausgewertet

    for( MD md; fin >> md; )
    

    soweit ich es sehe.
    Ich habe versucht den teil auszulassen aber
    dann tut er nichts
    und in die neue Datei die erstellt wird schreibt er nur eine null. Warum ?



  • for( MD md; fin >> md; ) 
        {  // auswerten 
           fin >> MD ; 
             // .. summieren 
        }
    

    ist halt falsch.

    for( MD md; fin >> md; ) 
        {
    //                     so greifst du auf die elemente der struktur zu
            std::cout << md.hours_worked << '\n';
    //      auswerten + summieren + ...
        }
    
    ofstream myFile;  
       myFile.open ("C:/Ruby193/value.csv");
    
       if (myFile)
       {
    
           myFile << fin ;
             // Dateien schliessen / ich weiß nicht ob dies überhaupt notwendig ist ? :)
          myFile.close();
    
       }  
        return 0;
    }
    

    ->

    ofstream myFile("C:/Ruby193/value.csv");
       myFile << 56789; /* hier setzt du das ein, was du schreiben möchtest - z.bsp. den namen der summe aus hours_worked*/
    }
    

    bb



  • Danke erstmal für deine Antwort (Die Gold richtig ist ) 🙂 aber das hab ich schon in einem neuem Forum erfahren 🙂

    http://www.c-plusplus.net/forum/308958

    hier stoße ich aber wieder auf Probleme z.bsp : schleifen Problem villt magst du mir mit deinem Wissen dort weiter helfen ? gruß cevin 🙂


Anmelden zum Antworten