.txt Datei - Jede zweite Zeile "auslassen"



  • Du liest nur bei jedem zweiten Durchgang eine Zeile. Das ist nicht das, was du willst.


  • Mod

    phanzy schrieb:

    Warum schreibst du nicht zwei Mal getline(); , verwendest aber nur jeweils die, welche du haben möchstest?
    Also in diesem Fall immer die erste?

    Oder besser noch, einmal getline, einmal ignore bis zum nächsten Zeilenumbruch. getline macht intern durchaus komplexe Dinge (zumindest die string-Version), die man sich lieber sparen will, wenn man sie nicht braucht.



  • manni66 schrieb:

    Du liest nur bei jedem zweiten Durchgang eine Zeile. Das ist nicht das, was du willst.

    Aaach *facepalm*, klar! Immer diese Denkfehler.

    Noch eine frage ...
    std::cin.ignore( <was muss denn hier rein?>, '\n'); <- so gemeint?

    Aber sonst, das macht prinzipiell in meinem Fall keinen Unterschied...

    Vielen Dank für die schnellen Antworten!

    mfg
    HarteWare



  • Ich denke:

    std::cin.ignore(256,'\n');   // ignore until new line
    

    Wobei 256 natürlich willkürlich gewählt ist.


  • Mod

    HarteWare schrieb:

    std::cin.ignore( <was muss denn hier rein?>, '\n'); <- so gemeint?

    Ja, so ist das gemeint. Als Wert für wie viele Zeichen übersprungen werden sollen, könntest du eine sehr große Zahl nehmen, aber es gibt noch einen Sonderwert, nämlich das Maximum des Typen streamsize . Das heißt dann "unendlich". Das Maximum kannst du aus dem limits-Header erfahren:

    std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n');
    

    Ja, ist ein bisschen umständlich zu schreiben :p . Glücklicherweise braucht man das nicht so oft. Oder wenn doch, dann definiert man sich eben eine Konstante als Kurzschreibweise.


  • Mod

    Oder man schreibt sich direkt eine kleine Helferfunktion:

    istream& ignore_until( istream& is, char ch = '\n' )
    {
        return is.ignore( std::numeric_limits<std::streamsize>::max(), ch );
    }
    

    (ungetestet)

    Übrigens, was soll denn diese Abbruchbedingung:

    while( file.is_open() )
    

    Da schaudert es mir.
    ➡

    std::string line;
        while( std::getline(file,line) )
        {
            temp_lines.push_back( std::move(line) ); // move ist optional
            file.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );    
        }
    


  • Huhu,

    Dankesehr, funktioniert einwandfrei. Irgendwas mit numeric_limits hatte ich noch im Kopf, schonmal in anderen Threads gelesen.

    In dem Fall wäre die Sache so weit geklärt. Man lernt nie aus...

    mfg
    HarteWare

    EDIT: Ein Problem hätte ich noch:

    Zeile beginnt mit string

    a
    a
    b
    a
    b
    a
    a
    etc. (kein festes Muster)

    ich will nur Zeilen haben mit Anfangsstring a. Die anderen ist nicht wichtig.

    Nun habe ich Sachen versucht wie

    Nur wenn: string[4] == "char, welchen nur string a an fünfter Stelle hat"
    Dann: schreib in die Datei
    

    Jedoch klappt es nicht. Es werden weiterhin alle strings aus dem vector in die Datei geschrieben... Wie würde man korrekter Weise sowas angehen?



  • Dann liest du auch nur die Zeilen ein, die du haben willst:

    while (std::getline(file, line))
    {
        if (line[0] == 'a')
            lines.push_back(std::move(line));
    }
    


  • Nathan schrieb:

    Dann liest du auch nur die Zeilen ein, die du haben willst:

    while (std::getline(file, line))
    {
        if (line[0] == 'a')
            lines.push_back(std::move(line));
    }
    
    std::string line;
    while( std::getline( file, line ))
    {
        if( line[4] == 'n' )
            temp_lines.push_back( line );
        file.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
    }
    

    wobei gewollter "Startstring Teil" (ST) -> "Login" und ungewollter ST -> "Log Out"

    Der vector bleibt leider leer, das war auch mein Ansatz (sowohl beim Schreiben probiert, als auch beim Lesen)...

    mfg
    HarteWare



  • HarteWare schrieb:

    Der vector bleibt leider leer[..]

    Klar, Du ignorierst ja auch nicht die Zeile, die Du geprüft hast.


  • Mod

    Bitte schreib nicht so etwas:

    std::getline( file, line )
     if( line[4] == 'n' )
       // ...
    

    Das schreit ja geradezu nach Ärger. Besser:

    std::getline( file, line )
     if( line.length() > 4 && line[4] == 'n' )
       // ...
    


  • SeppJ schrieb:

    Das schreit ja geradezu nach Ärger. Besser:

    std::getline( file, line )
     if( line.length() > 4 && line[4] == 'n' )
       // ...
    

    Das ist auch nicht richtig, wenn der Stream in einem Fehlerstatus ist.

    http://ideone.com/i0d1P6


  • Mod

    Schreihals schrieb:

    SeppJ schrieb:

    Das schreit ja geradezu nach Ärger. Besser:

    std::getline( file, line )
     if( line.length() > 4 && line[4] == 'n' )
       // ...
    

    Das ist auch nicht richtig, wenn der Stream in einem Fehlerstatus ist.

    http://ideone.com/i0d1P6

    Das ist nur als ungefähre Richtungsangabe zu verstehen, ich wollte jetzt nicht noch eine weitere Ebene an Abfragen hinzu fügen. Aber guter Hinweis an Leute, die das Beispiel zu wörtlich genommen hätten.



  • Hallo,

    Caligulaminus schrieb:

    HarteWare schrieb:

    Der vector bleibt leider leer[..]

    Klar, Du ignorierst ja auch nicht die Zeile, die Du geprüft hast.

    Wie ist das zu verstehen? So? Denke ich hab das so falsch verstanden...

    std::string line;
        while( std::getline(file,line) )
        {
            if( line.length() > 4 && line[4] == 'n')
            {
                temp_lines.push_back( line ); // move ist optional
                file.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
            }
            file.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
        }
    

    Stimmt, das Programm ist relativ gesehen recht unzuverlässlich und auch nicht wirklich universell verwendbar, aber ich möchte es nur für eine ganz bestimmte Aufgabe. Aber Danke für die Hinweise, nichts spricht dagegen sauber zu arbeiten.

    mfg
    HarteWare



  • Der stream hat einen Marker für die aktuelle Leseposition.
    Bei getline(..., '\n') wird der Marker auf die nächste Zeile gesetzt (und der Inhalt zwischen der vorherigen Position und der aktuellen in einen String gespeichert).
    Bei ignore(..., '\n') wird der Marker (nur) auf die nächste Zeile gesetzt.

    Gegeben sei folgender Dateiinhalt:

    0123m
    0123n
    0123o
    

    Wo steht der Lesemarker nach dem ersten Schleifendurchlauf? Welchen Inhalt hat line?
    Wie sieht es nach dem zweiten Durchlauf aus?

    std::string line;
        while( std::getline(file,line) )
        {
            if( line.length() > 4 && line[4] == 'n')
            {
                temp_lines.push_back( line ); // move ist optional
                file.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
            }
            file.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
        }
    

    Fällt Dir was auf?



  • std::string mystring;
    mystring = "blablabla"

    if(mystring[3] == 'a')
    writeToFile(mystring);



  • Namenloser324 schrieb:

    std::string mystring;
    mystring = "blablabla"

    if(mystring[3] == 'a')
    writeToFile(mystring);

    oh lol hab die zweite Seite nicht gesehen haha einfach ignorieren



  • Furble Wurble schrieb:

    Gegeben sei folgender Dateiinhalt:

    0123m
    0123n
    0123o
    

    Wo steht der Lesemarker nach dem ersten Schleifendurchlauf? Welchen Inhalt hat line?
    Wie sieht es nach dem zweiten Durchlauf aus?

    Fällt Dir was auf?

    Hallo,

    Also als erstes fällt mir auf, dass dieser Thread theoretisch nach Natans Post schon hätte gelöst sein sollen, jedoch ist dem in der Praxis nicht so... 😞
    Na gut:
    Nach dem ersten Durchlauf:

    0123m
    0123n 
    0123o <- Lesemarker
    Inhalt: "0123m"
    

    Nach dem Zweiten:
    nada, std::getline wird fehlschlagen

    while( getline( file, line )) // Diese Zeile schlägt fehl. Habs getestet. 
    
    //======================================
    while( std::getline( file, line ))
    {
        std::cout << line << '\n';
    }
    

    Output:

    Press <RETURN> to close this window...
    

    Ich finds echt toll, das so durchhaltend versucht wird mir zu helfen

    mfg
    HarteWare



  • HarteWare schrieb:

    Also als erstes fällt mir auf, dass dieser Thread theoretisch nach Natans Post schon hätte gelöst sein sollen, jedoch ist dem in der Praxis nicht so... 😞
    Na gut:
    Nach dem ersten Durchlauf:

    0123m
    0123n 
    0123o <- Lesemarker
    Inhalt: "0123m"
    

    Nach dem Zweiten:
    nada, std::getline wird fehlschlagen

    Sicher?
    Hast Du's mal ausprobiert?

    HarteWare schrieb:

    while( getline( file, line )) // Diese Zeile schlägt fehl. Habs getestet. 
    
    //======================================
    while( std::getline( file, line ))
    {
        std::cout << line << '\n';
    }
    

    Output:

    Press <RETURN> to close this window...
    

    Das sollte eigentlich jede Zeile eines Files ausgeben.
    Wenn Du jetzt noch die gesuchten Zeilen in einen Vektor einfügst ist die Aufgabe doch gelöst?!



  • oh man... kann es sein, dass es ihm net passt, wenn vor jeder Zeile im Dokument noch en bissle whitespace ist? Naja das Einlesen hat sich nun geklärt...

    Ich möcht mich nochmals bei allen Helfenden bedanken 👍

    mfg
    HarteWare


Anmelden zum Antworten