Aus eine Datei lesen



  • @dooni sagte in Aus eine Datei lesen:

    @Swordfish Wie ich aus eine Datei Zahlen lese
    Beispiel

    Geben Sie den Dateinamen ein: example.txt
    Die sortierte Folge ist:
    1 2 3 4 5 6 7 8 9
    Das Minimum ist 1
    Das Maximum ist 9
    Der Median ist 5
    und das soll in so eine Form sein
    void fillfile(std::vector<int>& v, const std::string& filename);

    fstream aufmachen, inhalt lesen (mit zb getline aus der std::getline() oder fstream.getline() müsste beides gehen, du must wissen wie es gespeichert ist, da du mit getline eine komplette zeile bekommst. (kannst auch mit Buffernarbeiten, aber das musst du selbst ergoogeln).
    Deinen Stream musst du in eine c_str oder string (oder was auch immer) speichern und dann in ein int[] oder vector<int>(oder was auch immer kannst auch ne liste nehmen) konvertieren in dem du halt die Zahlen aus dem string nimmst (durch string.substr() o.ä.) die dann in ein int castest (ACHTUNG: (int)"1" oder '1'== 49 != 1 da ein char bzw string immer in den entsprechenden ASCII code gecastet wird) und dann hast du die Zahl.

    Also garnicht mal so viel anders als du es mit deinem vector filename gemacht hast.



  • @Darktutnix sagte in Aus eine Datei lesen:

    inhalt lesen (mit zb getline aus der std::getline() oder fstream.getline() müsste beides gehen, du must wissen wie es gespeichert ist, da du mit getline eine komplette zeile bekommst. (kannst auch mit Buffernarbeiten, aber das musst du selbst ergoogeln).
    Deinen Stream musst du in eine c_str oder string (oder was auch immer) speichern und dann in ein int[] oder vector<int>(oder was auch immer kannst auch ne liste nehmen) konvertieren in dem du halt die Zahlen aus dem string nimmst (durch string.substr() o.ä.) die dann in ein int castest (ACHTUNG: (int)"1" oder '1'== 49 != 1 da ein char bzw string immer in den entsprechenden ASCII code gecastet wird) und dann hast du die Zahl.

    W. T ... Heck!?

    #include <vector>
    #include <string>
    #include <fstream>
    #include <iterator>
    
    void fillfile(std::vector<int> &values, std::string const &filename)
    {
    	std::ifstream is{ filename };
    	values = std::vector<int>{ std::istream_iterator<int>{ is }, std::istream_iterator<int>{} };
    }
    

    Ohne istream_iterator<>:

    #include <vector>
    #include <string>
    #include <fstream>
    
    void fillfile(std::vector<int> &values, std::string const &filename)
    {
    	std::ifstream is{ filename };
    	for (int value{}; is >> value; values.push_back(value));
    }
    

    @dooni sagte in Aus eine Datei lesen:

    while(!inFile.eof())
    {
        getline(inFile, word);
        // ...
    

    Ist fast nie korrekt. Du machst

    • auf Dateiende prüfen
    • lesen (eventuell Dateiende oder Fehler)
    • verarbeiten (eventuell Müll)

    richtig rum:

    • lesen
    • auf Fehler prüfen
    • verarbeiten


  • Ich möchte noch was zur Namensgebung der Funktionen beitragen:

    Ein Funktion, die Daten aus einer Datei in einen Container liest, sollte auf keinen Fall "fillFile" heißen, weil das zu Deutsch "befülle Datei" heißt und genau das Gegenteil bedeutet.
    Benenne deine Funktionen so aussagekräftig wie möglich!

    Z.B. "readDataFromFile" und "writeDataToFile" oder "generateRandomNumbers"



  • @Swordfish sagte in Aus eine Datei lesen:

    @Darktutnix sagte in Aus eine Datei lesen:

    inhalt lesen (mit zb getline aus der std::getline() oder fstream.getline() müsste beides gehen, du must wissen wie es gespeichert ist, da du mit getline eine komplette zeile bekommst. (kannst auch mit Buffernarbeiten, aber das musst du selbst ergoogeln).
    Deinen Stream musst du in eine c_str oder string (oder was auch immer) speichern und dann in ein int[] oder vector<int>(oder was auch immer kannst auch ne liste nehmen) konvertieren in dem du halt die Zahlen aus dem string nimmst (durch string.substr() o.ä.) die dann in ein int castest (ACHTUNG: (int)"1" oder '1'== 49 != 1 da ein char bzw string immer in den entsprechenden ASCII code gecastet wird) und dann hast du die Zahl.

    W. T ... Heck!?

    #include <vector>
    #include <string>
    #include <fstream>
    #include <iterator>
    
    void fillfile(std::vector<int> &values, std::string const &filename)
    {
    	std::ifstream is{ filename };
    	values = std::vector<int>{ std::istream_iterator<int>{ is }, std::istream_iterator<int>{} };
    }
    

    in seinem eigenen code hat er die auch schon nicht verwendet xD ... glaube nicht das er die jetzt verwenden würde. (aber ja ist deutlich einfacher, aber benötigt auch mehr Wissen/verständnis über Vektoren.)

    Ohne istream_iterator<>:

    #include <vector>
    #include <string>
    #include <fstream>
    
    void fillfile(std::vector<int> &values, std::string const &filename)
    {
    	std::ifstream is{ filename };
    	for (int value{}; is >> value; values.push_back(value));
    }
    

    Die so freihe verwendung von for find ich gut 😃 danke für den Tipp. (dachte immer ist extrem unflexibel und man kann nur sowas wie for(int i = 0 ... i++) zb machen oder for(int i: liste<int>))
    Wird bei ìnt value{} ein temporäre neuer leerer int speicher auf dem Stack erzeugt, oder verstehe ich das falsch?
    Und >> funktioniert bei jedem Stream um die nicht interpretierbaren sachen fallen zu lassen (leerzeichen, buschstaben und alles was kein int sein könnte)?



  • @Darktutnix sagte in Aus eine Datei lesen:

    Wird bei ìnt value{} ein temporäre neuer leerer int speicher auf dem Stack erzeugt, oder verstehe ich das falsch?

    Es wird eine int-Variable namens "value" mit "automatic storage duration" erzeugt und mit 0 initialisiert. Wahrscheinlich wird diese nicht auf dem Stack liegen, sondern nur in einem Prozessor-Register vorliegen. Das hängt aber vom Zielsystem, dem Compiler und den Optimierungseinstellungen ab.

    Und >> funktioniert bei jedem Stream um die nicht interpretierbaren sachen fallen zu lassen (leerzeichen, buschstaben und alles was kein int sein könnte)?

    Whitespace wird übersprungen (kannst du mit skipws einstellen), bei anderen Zeichen geht der Stream in einen Fehlerstatus und die Schleife wird abgebrochen.



  • @wob sagte in Aus eine Datei lesen:

    @Darktutnix sagte in Aus eine Datei lesen:

    Wird bei ìnt value{} ein temporäre neuer leerer int speicher auf dem Stack erzeugt, oder verstehe ich das falsch?

    Es wird eine int-Variable namens "value" mit "automatic storage duration" erzeugt und mit 0 initialisiert. Wahrscheinlich wird diese nicht auf dem Stack liegen, sondern nur in einem Prozessor-Register vorliegen. Das hängt aber vom Zielsystem, dem Compiler und den Optimierungseinstellungen ab.

    also das gleiche wie int value = 0? oder gibts da einen unterschied?

    ^^ sorry fürs nerven (aber danke fürs erklären)



  • @Darktutnix sagte in Aus eine Datei lesen:

    also das gleiche wie int value = 0? oder gibts da einen unterschied?

    Kein Unterschied. Ich bevorzuge die = 0-Schreibweise.



  • @Darktutnix sagte in Aus eine Datei lesen:

    also das gleiche wie int value = 0? oder gibts da einen unterschied?

    Nee kein Unterschied. Ich finde allerdings

    int value = 0;
    

    lesbarer weil klar ist was passiert.

    In diesem Fall

    int value {};
    

    Kann man nur eine Annahme treffen, was in dem Fall getan wird.



  • @It0101 sagte in Aus eine Datei lesen:

    Kann man nur eine Annahme treffen, was in dem Fall getan wird.

    Nö, auch da braucht man nicht mit Annahmen zu arbeiten.



  • @wob sagte in Aus eine Datei lesen:

    @It0101 sagte in Aus eine Datei lesen:

    Kann man nur eine Annahme treffen, was in dem Fall getan wird.

    Nö, auch da braucht man nicht mit Annahmen zu arbeiten.

    Ich finds in dem Anwendungsfall besser wenn klar da steht, was getan wird, weil selbst ein Grundschulkind versteht was dort passiert.

    Wenns um Narrowing geht, ist die initializerlist mit {} natürlich besser.