Probleme beim Einlesen einer Text-Datei



  • Hallo,

    ich hab den Quellcode noch nicht ganz verstanden.
    Kannst du mir den nochmal kurz erklären ?

    Wäre nett.

    Danke !



  • hmm..... zu allererst: wenn du auch nach dieser Erklaerung nicht alles verstehst, stell sicher, dass du dich mit stringstreams auskennst. istringstreams funktionieren genau so wie cin oder ifstream, ostringstreams genauso wie cout oder ofstream... Nur dass sie ihre Daten nicht von der Konsole holen (bzw. dorthin schreiben), sondern in einen String....
    Dann: schau dir z. B. auf www.cppreference.com mal die Referenz von std::string an, damit du auch weisst, was fuer Methoden so ein string eigentlich hat...

    So, jetzt zum Code:

    ifstream file("foo.txt");
        string line;
    
        // string::size_type ist ein Datentyp fuer Laengenangaben. Ich haett genauso gut auch int nehmen koennen
        string::size_type start = 0;
        string::size_type end = 0;
    
        // liest eine Zeile aus der Datei und speichert sie in line
        getline(file, line);
    
        string name;
        string alter;
        string wohnort;
    
        // line.find_first_of('*', start)... schau mal unter http://www.cppreference.com/cppstring/find_first_of.html
        // er sucht also nach dem Zeichen '*', und startet seine Suche bei line[start]... d.h. start gibt an, ab wo gesucht werden soll
        // end = line.find_first_of('*', start) speichert die Position, wo das '*' gefunden wurde, in end
        // und schliesslich: wenn find_first_of() das Zeichen '*' nicht im String finden kann, wird string::npos zrueckgegeben....
        // wenn also kein '*' nach line[start] mehr gefunden wird, dann bricht die Schleife ab
        while ((end = line.find_first_of('*', start)) != string::npos)
        {
            // ok, hier wird also ein istringstream erstellt... das ist wie gesagt sowas aehnliches wie ein ifstream...
            // nur werden die Daten nicht aus einer Datei gelesen, sondern aus einem string... in diesem Fall aus
            // line.substr(start, end - start). substr() liefert einen Teilstring (einen "substring") aus
            // line, der bei line[start] startet und (end - start) Zeilen lang ist
            // guckst du auch hier: http://www.cppreference.com/cppstring/substr.html
            istringstream istr(line.substr(start, end - start));
    
            // ok, das funktioniert genauso, wie bei einem ifstream oder bei cin:
            // Wenn du da 3 Werte einlesen moechtest, wuerdest du ja auch einfach nur
            // cin >> string1 >> string2 >> string3
            // schreiben. Das hier funktioniert genauso...
            istr >> name >> alter >> wohnort;
    
            // damit beim naechsten Schleifendurchgang nicht wieder das gleiche '*' gefunden wird,
            // sondern das naechste, setzen wir den Startwert fuer die Suche weiter nach rechts
            start = end + 1;
    
            // ..... bearbeiten der aktuellen Daten
        }
    

    So, that's it, ich hoff das war jetzt verstaendlich 🙂



  • Hallo,

    Also wird die gesamte Textzeile in einen string eingelesen und im String werden dann die Operationen gemacht ?
    Was ist wenn die Textdatei einen Zeilenumbruch hat ?
    Kann man folgendermaßen vorgehen:

    ...
    while (getline(file, line))
    {

    while((end = line.find_first_of('*', start)) != string::npos)
    {
    ...}

    }

    Ich lese also immer eine Zeile ein und untersuche die dann !

    Kann das so finktionieren ?



  • ja, so in der Art musst du das sogar machen! 🙂

    getline liesst naehmlich immer nur 1 Zeile raus, d.h. wenn die Datei mehrere Zeilen hat, musst du auch entsprechend oft getline() aufrufen 🙂



  • Hallo,

    ja aber ich muss doch verhindern, dass er jedes Mal die selbe Zeile einliest !
    Kann man irgendwie einen Zeilenumbruch erzwingen ?

    Tschüss



  • while ( getline( file, line ) )
    

    liest ja solange Zeilen ein, bis die Datei zuende ist.



  • while (getline(file, line))

    nein !

    so:

    while (!file.eof())          // liesst die gesamte datei ein
    {
        if(file.eof()){break;};  // verhindert die letzte doppelte zeile
        iStr << string1 << string2 << string3 << endl;
    };
    

    //edit schreibfehler (das übliche halt 😉 )



  • enno-tyrant schrieb:

    while (getline(file, line))

    nein !

    Warum nicht?

    Caipi



  • Caipi schrieb:

    enno-tyrant schrieb:

    while (getline(file, line))

    nein !

    Warum nicht?

    Caipi

    weil es nur eine zeile einliest



  • enno-tyrant schrieb:

    Caipi schrieb:

    enno-tyrant schrieb:

    while (getline(file, line))

    nein !

    Warum nicht?

    Caipi

    weil es nur eine zeile einliest

    Nö. Vergl.

    #include <iostream>
    #include <string>
    #include <fstream>
    using namespace std;
    
    int main()
    {
            ifstream in("test.txt");
            if(in.is_open())
            {
                    string str;
                    while(getline(in, str))
                            cout << str << endl;
            }
            return 0;
    }
    

    (Zumindest bei mir, liest es die ganze Datei ein) 😉

    Caipi



  • gut...gebe mich geschlagen 😃



  • Hallo,
    die Version von Blue Tiger funktioniert 1a.

    Aber die hier scheint nicht zu gehen, warum ?

    string t,s,v,n;
    int p;
    istringstream iss(t);
    ifstream fin("Test.txt");
    
    while(!fin.eof())
    { 
       if(!file.eof()) break;
       getline(fin,t);
       iss>>n>>v>>p>>s;
       cout>>n>>v>>p>>s;
    }
    /*
    Test.txt
    Name Vorname Zahl  Ort
    Name Vorname Zahl  Ort
    .
    .
    . 
    */
    

    Müsste doch theoretisch funktionieren oder ?

    Danke.



  • lightning schrieb:

    if(!file.eof()) break;

    wohl eher:

    if(file.eof()) break;
    


  • Das stimmt allerdings, aber damit ist der Fehler nicht beseitigt.

    Ich bekomme diese Ausgabe:

    -858993460

    Und zwar für jede Zeile in der Textdatei !

    Was könnte noch falsch sein ?

    Danke im Voraus.



  • Ein paar Fragen
    Was ist file (meinst du fin?). Das ist aber an der Stelle sinnlos.
    Wo füllst du iss mit t ? Da oben ist das zu zeitig, immerhin ist t noch nicht belegt.
    Was soll das mit dem cout (einlesen ?)
    Also warum nicht:

    string t,s,v,n; 
    int p; 
    stringstream iss; 
    ifstream fin("Test.txt"); 
    
    while(getline(fin,t)) 
    { 
       iss.str(t);
       iss >> n >> v >> p >> s; 
       cout << n << v << p << s; 
    }
    


  • Hallo,

    ja die Fehler "cout>>" und "file" habe ich nur hier gemacht, nicht im Quellcode.
    Ich habe den Fehler auch gefunden.
    Ich dachte wenn in t der string steht, dann wird er dem iss dynamisch zugewiesen.
    Ich habe die Erstellung von iss in der schleife nach der getline Anweisung gemacht.

    Jetzt geht alles !

    Trotzdem Danke.


Anmelden zum Antworten