Schreiben von Strings in Datei



  • Hallo, ich möchte viele verschiedene Informationen (Strings) in eine Datei schreiben. Während der Ausführung des Programms können ständig neue solche Informationen hinzukommen.
    Ist es nun klüger:

    a) immer, wenn ein solcher neuer String vorliegt, das Dokument zu öffnen, den String hineinzuschreiben und das Dokument wieder zu schließen

    oder

    b) einen großen langen String zu erzeugen, der erst am Ende der Ausführung des Programms als ganzes in das Dokument geschrieben wird

    ?



  • Die einfache Variante:

    #include <cstdio>
    
    void main()
    {
       FILE *pFile = fopen("Filename.txt", "a+");
       char* string = "Hello World!!!";
       fprintf("%s", string);
       string = (char*) "Hallo Welt";
       fprintf("%s", string);
       fclose(pFile);
    }
    

    Du solltest das Dokument eventuell statisch o. Global verwalten, den öffnen und schließen ist mit erheblichen Zeitaufwand verbunden.

    Falls du ne Klasse hast:
    Im Konstruktor öffnen und im Destruktur schließen.



  • Also bitte, dies ist das C++ Forum, also bitte auch C++ Code.

    1. cstdio.h gibt es nicht, entweder stdio.h (C) oder cstdio (C++, aber eigentlich gar nicht)
    2. void main () ist weder gültiges C noch gültiges C++
    3. std::strings (die gar nicht inkludiert sind) haben einen Konstruktor für char*-Strings, der (C-)Cast ist unnötig.
    4. In C++ benutzt man für so etwas Streams

    Ich weiß, dass es nur ein Beispiel war, aber ein wenig sorgfältiger gehts schon

    Zur eigentlichen Frage:
    Je nachdem, wie das Programm aufgebaut ist, halte ich es für sinnvoll, die ganzen Strings, die da auflaufen an eine Liste dranzuhängen und dann am Ende in eine Datei zu schreiben. Immer wieder öffnen oder offen halten ist nicht so Wahre.
    Dem Destruktor Ansatz stimme ich aber zu.

    #include <string>
    #include <fstream>
    #include <list>
    
    class Strings
    {
    public:
        typedef std::list<std::string> ListType;
    
        Strings (std::string Name) : mName (Name) {}
    
        void push (std::string s) { mList.push_back (s); }
        void push (char* s) { push (std::string (s)); }
    
        ~Strings ()
        {
            std::ofstream File (Name.c_str ());
            for (ListType::iterator i = mList.begin (); i != mList.end (); ++i)
                File << *i << std::endl;
        }
    private:
        ListType mList;
        const std::string mName;
    };
    

    So würds ich glaub ich machen. Strings sollte man dann noch zum Singleton machen, so würds am Anfang gebaut und am Ende zerstört.



  • In C++ gibts nur eine "wahre" Variante:

    #include <fstream>
    #include <string>
    
    int main() 
    {
        std::ofstream file("file.tmp");
        // hier fehlerüberprüfung!
        std::string text("hello world");
        file << text;
    }
    

    Sieht irgendwie auch einfacher aus als das obere.

    Gruß



  • Es ist ja auch die "echte" C++ variante.



  • FireFlow schrieb:

    In C++ gibts nur eine "wahre" Variante:

    #include <fstream>
    #include <string>
    
    int main() 
    {
        std::ofstream file("file.tmp");
        // hier fehlerüberprüfung!
        std::string text("hello world");
        file << text;
    }
    

    Sieht irgendwie auch einfacher aus als das obere.

    Gruß

    So klappt es sehr gut, aber muss ich die Datei nicht noch irgendwie schließen?
    Dazu habe ich noch eine Frage. Das obige Programm funktioniert ja sehr gut, aber wieso geht das Folgende nicht auch?

    #include <fstream>
    #include <string>
    
    int main() 
    {
    
        std::string filename("name.txt");
        std::ofstream file(filename);
        std::string text("hello world");
        file << text;
    
    }
    


  • So klappt es sehr gut, aber muss ich die Datei nicht noch irgendwie schließen?

    Das macht der Stream selber im Destruktor.

    Dazu habe ich noch eine Frage. Das obige Programm funktioniert ja sehr gut, aber wieso geht das Folgende nicht auch?

    weil (warum auch immer) der fstream einen char* als Dateinamen erwartet und keinen String:

    std::ofstream file(filename.c_str());
    

    ist die Antwort dafür.



  • .filmor schrieb:

    #include <string>
    #include <fstream>
    #include <list>
    
    class Strings
    {
    public:
        typedef std::list<std::string> ListType;
    
        Strings (std::string Name) : mName (Name) {}
    
        void push (std::string s) { mList.push_back (s); }
        void push (char* s) { push (std::string (s)); }
    
        ~Strings ()
        {
            std::ofstream File (Name.c_str ());
            for (ListType::iterator i = mList.begin (); i != mList.end (); ++i)
                File << *i << std::endl;
        }
    private:
        ListType mList;
        const std::string mName;
    };
    

    Ohhhh 😮
    Ich weiß nicht aber irgendwie finde ich den Code richtig schöööön 😃 👍

    Was ist ein Singleton, das hört man ja auch öfters 😕



  • Bzg. dem Code: Was ich nicht ganz nachvollziehen kann, ist, dass keine Referenzen zum Zuge kommen. Außerdem: warum wird für char* und std::string überladen? ...

    Bzg. Singleton: http://de.wikipedia.org/wiki/Singleton.

    Gruß Caipi



  • Das mit den Referenzen stimmt, kleine Unachtsamkeit 🙂 . Für char* hab ich überladen, weil ich mir nicht ganz sicher war, ob normale String-Literale ( "blabla" ) sonst auch genommen werden.

    EDIT: Naja, und selbst dann wärs const char*, ist also Quatsch.

    BTW, auf "Bezüglich" folgt ein Genitiv 😉


Anmelden zum Antworten