string in klasse


  • Mod

    zenit_ schrieb:

    sprintf(string,text_dateiname);

    Das wird dir sowas von verrecken, so schnell kannst du gar nicht stack corruption sagen.

    Er hat bloß einen seiner anderen Fehler als Fehler bei der Zuweisung interpretiert. Der Zuweisungsoperator ist für std::string selbstverständlich definiert.



  • Ich schätze, du willst den Text in die Datei "2 ist eine Primzahl.txt" schreiben und nicht in test.txt.

    Dann solltest du aber auch die test.txt schließen und anschließend deine neue Datei aufmachen. Du weist ja nur in deiner Klasse dem String dateiname den neuen Wert zu. dateiname hat mit der Datei erstmal nichts zu tun hat, du musst erst noch eine Datei mit dem Namen öffnen.

    void ein_und_ausgabe::set_dateiname(string text_dateiname)
    {
        file.close(); // Alte Datei schließen
        dateiname = text_dateiname;
        file.open(dateiname, ios_base::out); // Neue Datei öffnen
    }
    

    (ungetestet)

    PS.: string i; im Konstruktor ist unnötig, da nicht gebraucht.



  • Rhombicosidodecahedron schrieb:

    Ähm, wie "geht nicht"? Wir raten nicht gerne.

    Aber einige (unvollstänige) Bemerkungen:

    • Bei zwei Methoden/Funktion wurdne der Rückgabewert void nicht angegeben

    Hm? Kann ich nicht erkennen, ausser du meinst den Konstruktor und Destruktor.

    • Eine wahrscheinlich wichtige Funtkion wurde aufgerufen
    • Wobei du dessen Inhalt auch in eine andere besondere Funktion hättest einfügen können, welche versteckt aufgerufen wird.

    😕 Mir erschliesst sich nicht ganz wovon du redest 🙂


  • Mod

    inter2k3 schrieb:

    • Eine wahrscheinlich wichtige Funtkion wurde aufgerufen
    • Wobei du dessen Inhalt auch in eine andere besondere Funktion hättest einfügen können, welche versteckt aufgerufen wird.

    😕 Mir erschliesst sich nicht ganz wovon du redest 🙂

    Er meint, dass die ein_und_ausgabe-Klasse ohne vorherigen Aufruf von set_dateiname() ganz schlimme Dinge macht, wenn man dann schreiben() aufruft. Sowas gehört daher in den Konstruktor. Zumal der Threadersteller hier völlig sinnlos eigene Konstruktoren und Destruktoren definiert.



  • Was soll denn schlimmes gemacht werden? Es wird der String i in die Datei test.txt geschrieben (die ja im Konstruktor geöffnet wurde). Kann da nichts schlimmes sehen.



  • Hmm, ich würd sowas bauen:

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <exception>
    #include <sstream>
    
    class ein_und_ausgabe
    {
    public: 
       ein_und_ausgabe(std::string dateiname);
       ~ein_und_ausgabe();   
    
       const std::string& dateiname() const { return m_dateiname; }
       bool istOffen() const { return m_stream.is_open(); }
    
       std::ofstream& operator<<(const std::string& t);
    
    private:
       std::ofstream m_stream;
       std::string m_dateiname;
    };
    
    ein_und_ausgabe::ein_und_ausgabe(std::string dateiname)
    : m_dateiname(dateiname)
    {
       m_stream.open(dateiname.c_str());
       if ( m_stream.is_open() == false )
       {
          std::stringstream ss;
          ss << "Kann Datei '" << m_dateiname << "' nicht öffnen";
          throw std::exception(ss.str().c_str());
       }
    }
    
    ein_und_ausgabe::~ein_und_ausgabe()
    {
       m_stream.close();
    }
    
    std::ofstream& ein_und_ausgabe::operator<<(const std::string& t)
    {
       m_stream << t;
       return m_stream;
    }
    
    int main()
    {
       try
       {
         ein_und_ausgabe ea("Test.txt");
         if ( ea.isOffen() )
         {
             ea << "Hello Stream!";   
         }
       }
       catch(std::exception& e)
       {
           std::cout << "Ausnahmefehler! Meldung: " << e.what() << std::endl;
       }
    }
    

    Hinweis: Unter msvc kein Problem, aber der mingw (g++) kennt kein exception-constructor der einen string als Fehlermeldung akzeptiert.
    Leider ist das im Standard scheinbar nicht definiert wie der Constructor von exception auszusehen hat -.-.
    rya.



  • Scorcher24 schrieb:

    Leider ist das im Standard scheinbar nicht definiert wie der Constructor von exception auszusehen hat -.-.
    rya.

    Doch, das ist definiert. Siehe Standard 18.6.1 1-3
    Für std::exception selber gibt es keinen Konstruktor der etwas übernimmt (CopyCtor ausgenommen).
    Da muss man sich was draus ableiten, oder die vordefinierten Typen von stdexcept nutzen.


  • Mod

    @Scorcher24: Warum schließt du die Datei im Destruktor? 😕



  • ok, danke für die vielen antworten, werde sie alle mal in ruhe durchlesen



  • Braunstein schrieb:

    Scorcher24 schrieb:

    Leider ist das im Standard scheinbar nicht definiert wie der Constructor von exception auszusehen hat -.-.
    rya.

    Doch, das ist definiert. Siehe Standard 18.6.1 1-3
    Für std::exception selber gibt es keinen Konstruktor der etwas übernimmt (CopyCtor ausgenommen).
    Da muss man sich was draus ableiten, oder die vordefinierten Typen von stdexcept nutzen.

    Hmm, danke aber da finde ich die M$-Implementation echt besser...

    @SeppJ
    Warum nicht? Kommt immer drauf an, was man möchte. Es ist zumindest nichts falsches dabei... zumal die Klasse nen reiner Wrapper für ofstream darstellt und eigentlich relativ sinnlos wäre in einem ernsthaften Programm, ausser man implementiert ein gewisses Verhalten beim Lesen&Schreiben.
    rya.



  • Scorcher24 schrieb:

    Hmm, danke aber da finde ich die M$-Implementation echt besser...

    hat alles vor und nachteile.
    string in der exception klasse fuehlt sich aber falsch an, da bad_alloc fliegen koennte...

    Warum nicht?

    weils unnoetig ist. der dtor von fstream raeumt selber auf.



  • Shade Of Mine schrieb:

    Scorcher24 schrieb:

    Hmm, danke aber da finde ich die M$-Implementation echt besser...

    hat alles vor und nachteile.
    string in der exception klasse fuehlt sich aber falsch an, da bad_alloc fliegen koennte...

    Hmm, mag sein. Hab das nicht studiert :p. Aber nichts empfinde ich als schlimmer als ständige Exceptions ohne zu wissen wo der Fehler liegt. Gutes Beispiel hierfür wäre CEGUI. Viel zu viel Exceptions ohne gescheite Beschreibung des Fehlers.

    Shade Of Mine schrieb:

    Scorcher24 schrieb:

    Warum nicht?

    weils unnoetig ist. der dtor von fstream raeumt selber auf.

    Okay, aber schaden tuts auch nicht 🤡.
    rya.



  • Scorcher24 schrieb:

    Hmm, mag sein. Hab das nicht studiert :p. Aber nichts empfinde ich als schlimmer als ständige Exceptions ohne zu wissen wo der Fehler liegt. Gutes Beispiel hierfür wäre CEGUI. Viel zu viel Exceptions ohne gescheite Beschreibung des Fehlers.

    Deshalb ist es wichtig tiefe Exception Hierachien zu haben.
    Weil eine Fehlerbeschreibung in der Exception ist OK. Aber viel besser ist eine eigene Exception Klasse fuer einen Fehlertyp. Denn dann kann man im Code darauf reagieren. zB die Aktion wiederholen, oder alternativen versuchen.

    Wenn nur eine std::exception fliegt, dann kann das alles bedeuten...

    Okay, aber schaden tuts auch nicht 🤡

    es schadet der coolness 😉



  • Shade Of Mine schrieb:

    Wenn nur eine std::exception fliegt, dann kann das alles bedeuten...

    Okay, aber schaden tuts auch nicht 🤡

    es schadet der coolness 😉

    man weiß nicht obs funktionierte und excpetions im detor sind böse



  • p;sep;se schrieb:

    es schadet der coolness 😉

    man weiß nicht obs funktionierte und excpetions im detor sind böse

    Keine Ahnung was du meinst. Das close im DTor ist unnoetig. Es gibt keine Situation wo es etwas anderes macht als der dtor vom fstream objekt nicht sowieso machen wuerde. exceptions fliegen hier in keinem fall.



  • Files im detor schließen ist eigentlich garkeine gute idee



  • p;sep;se schrieb:

    Files im detor schließen ist eigentlich garkeine gute idee

    Besser als eine close Funktion zu erfinden.

    PS: wenn du etwas sagen willst, dann formuliere das bitte aus und poste nicht jeden satz einzeln.



  • Der std::stream der im Detor aufräumt, ist keine gute Idee.
    Wenn close noch etwas ins File schreiben muss, weil noch kein flush kam, weißt du nicht obs funktionierte, weil das objekt dann weg ist. Und Exception werfen: http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.9



  • p;sep;se schrieb:

    man weiß nicht obs funktionierte und excpetions im detor sind böse

    Es wird sicher funktionieren, sonst gäbe es keine Funktion close(). Der Destruktor wird intelligent genug sein, ein close bleiben zu lassen, wenn der fstream gerade nicht offen ist. Und close wirft nur eine exception, wenn exceptions für das Objekt aktiviert sind (laut Doku).
    Und seit wann sind Exceptions im DTor böse? Ich behaupte das Gegenteil und sage Exceptions im DTor sind was wunderbares!
    Das was böse endet ist, wenn eine Exception den DTor verlässt. Wenn wirklich im DTor was passieren kann, musst du das alles fangen.

    Ich glaub aber deine Posts gehen stark in Richtung getrolle.



  • l'abra d'or schrieb:

    Und close wirft nur eine exception, wenn exceptions für das Objekt aktiviert sind (laut Doku).
    Und seit wann sind Exceptions im DTor böse? Ich behaupte das Gegenteil und sage Exceptions im DTor sind was wunderbares!
    Das was böse endet ist, wenn eine Exception den DTor verlässt. Wenn wirklich im DTor was passieren kann, musst du das alles fangen.

    Woher weißt du ob std::stream im Detor erfolgreich geschlossen wurde?


Anmelden zum Antworten