leerzeichen ... (nich ganz die standartfrage)



  • Dieser Thread wurde von Moderator/in SideWinder aus dem Forum DOS und Win32-Konsole in das Forum C++ verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • hm ... ok stimmt ...

    aber wie mach ichs richtig ?!



  • Hi,

    ungefähr so:

    char row[500]; // Zum speichern einer ganzen Zeile
      ifstream input("datei.dat"); // Stream öffnen
    
      while(input.good()) // ist quasi: solange nicht EOF
      {
        input.getline(row, 500); // Zeile in char-array schieben
        string zeile(row); // String Objekt aus dem char-array
      }
    

    Wenn Du explizit jedes einzelne Character brauchst, musst Du ja fast nur eine Methode ändern;)

    greetz
    SLi



  • Das kannste auch gleich sinnvoll mit

    ifstream input("datei.dat");
    string zeile;
    
    while(getline(input, zeile)) {
      // ...
    }
    

    Das löst allerdings das vorhandene Problem nicht. Ich denke, in diesem Fall geht es eher um sowas:

    #include <algorithm>
    #include <fstream>
    #include <iterator>
    #include <string>
    
    using namespace std;
    
    // ...
    
    ifstream input("datei.dat");
    string text;
    
    input.unsetf(ios::skipws); // Leerzeichen nicht überspringen
    copy(istream_iterator<char>(input), istream_iterator<char>(), back_inserter(text));
    


  • 0xdeadbeef schrieb:

    Das löst allerdings das vorhandene Problem nicht. Ich denke, in diesem Fall geht es eher um sowas:

    #include <algorithm>
    #include <fstream>
    #include <iterator>
    #include <string>
    
    using namespace std;
    
    // ...
    
    ifstream input("datei.dat");
    string text;
    
    input.unsetf(ios::skipws); // Leerzeichen nicht überspringen
    copy(istream_iterator<char>(input), istream_iterator<char>(), back_inserter(text));
    

    Wobei ich hier den range-Ctor von std::string verwenden würde.



  • danke !
    aber ... ääh .... könntest du das bitte erklären ?!



  • OK, ich kommentiere den Kram mal etwas ausführlicher

    #include <algorithm> // enthält u.a. copy
    #include <fstream> // für die file-streams
    #include <iterator> // für die stream-iteratoren
    #include <string> // für string
    
    using namespace std; // das ist nicht wirklich nötig, du könntest auch vor alle STL-Bezeichner std:: schreiben.
    
    // ...
    
    ifstream input("datei.dat");
    string text;
    
    // Normalerweise parst der operator>> für stl-streams phrasenweise, das
    // heißt, whitespaces (Leerzeichen, tabs, newlines etc) werden ignoriert.
    // Das Verhalten wird durch das skipws-flag kontrolliert, das hier auf false
    // gesetzt wird - das heißt, in Zukunft wird character-level geparst, Leerzeichen
    // werden auch gelesen.
    input.unsetf(ios::skipws);
    
    // und hier die eigentliche Arbeit. copy nimmt drei Iteratoren entgegen.
    // Iteratoren sind so ne Art Positionsangabe. In diesem Fall markieren die
    // ersten beiden den Bereich, der gelesen und der dritte die Position, an die
    // geschrieben werden soll. copy schreibt den Kram aus dem gegebenen
    // Bereich an die gegebene Position.
    // istream_iterator<char>(input) konstruiert einen Iterator auf dem Stream,
    // der auf die momentan aktuelle Position von input zeigt und zeichenweise
    // einliest. istream_iterator<char>() konstruiert einen Iterator, der quasi
    // hinter das Ende des Streams zeigt. Das bedeutet, der angegebene Bereich
    // ist in diesem Fall die ganze Datei.
    // back_inserter(ganze_datei) ist in diesem Fall das selbe wie
    // back_insert_iterator<string>(text). Es ist eine template-Funktion, die den
    // template-Parameter aus der eigenen Parameterliste bestimmt, das macht
    // den Aufruf einfacher. Jedenfalls konstruiert es einen Ausgabeiterator auf
    // dem String ganze_datei, der alles, was in ihn geschrieben wird, hinten an
    // ganze_zeile anhängt. Dementsprechend wird der Bereich (also die ganze
    // Datei) hinten an ganze_zeile angehängt, der zu dem Zeitpunkt leer ist.
    // Dementsprechend enthält ganze_zeile nachher den Inhalt der Datei.
    copy(istream_iterator<char>(input), istream_iterator<char>(), back_inserter(text));
    

    HumeSikkins hat recht, dass der Code nicht ganz optimal ist - Performancetechnisch wäre es besser, vorher die Länge der Datei zu bestimmen und den Speicher für ganze_zeile entsprechend vorher anzufordern. Im Interesse der Einfachheit habe ich das aber grad mal unterschlagen.



  • HumeSikkins hat recht, dass der Code nicht ganz optimal ist - Performancetechnisch wäre es besser, vorher die Länge der Datei zu bestimmen und den Speicher für ganze_zeile entsprechend vorher anzufordern. Im Interesse der Einfachheit habe ich das aber grad mal unterschlagen.

    wobei hume meinte, dass man eher sowas verwenden sollte anstatt copy

    string text(istream_iterator<char>(input), istream_iterator<char>());
    

    erklärung: man kann einen string nicht nur mit einem stringliteral initialisieren(string text("hallo"); ), sondern auch mit einer strecke, dh in einem array von position x bis position y. das funktioniert aber nicht nur mit zeigern wie sie in normalen feldern benutzt werden, sondern auch mit den sogenanten iteratoren. ein iterator verhält sich ähnlich wie ein zeiger, aber die daten die man durch ihn bekommt müssen nicht in einem array angeordnet sein.



  • otze schrieb:

    HumeSikkins hat recht, dass der Code nicht ganz optimal ist - Performancetechnisch wäre es besser, vorher die Länge der Datei zu bestimmen und den Speicher für ganze_zeile entsprechend vorher anzufordern. Im Interesse der Einfachheit habe ich das aber grad mal unterschlagen.

    wobei hume meinte, dass man eher sowas verwenden sollte anstatt copy

    string text(istream_iterator<char>(input), istream_iterator<char>());
    

    Ich habe nirgends vorgeschlagen das Lesen der Eingabe durch eine simple Funktionsdeklaration zu ersetzen. Was habe ich von einer Funktionsdeklaration text die einen string liefert und zwei Parameter, nämlich einen istream_iterator<char> sowie eine Funktion die einen istream_iterator<char> liefert und keine Argumente entgegennimmt, erwartet, wenn ich eigentlich input in ein string-Objekt einlesen will?

    Was ich vorschlug war sowas:

    // Man beachte die zusätzlichen Klammern
    string text((istream_iterator<char>(input)), istream_iterator<char>());
    

    oder für Leute die Code ganz gerne lesbar gestalten:

    istream_iterator<char> begin(input), end;
    string text(begin, end);
    


  • komisch, dass er das auch als funktionsdeklaration bewertet...ich dachte das input würde die sache klar machen...naja, wieder was gelernt


Anmelden zum Antworten