std::getline und "korrekte" Anzahl an newlines



  • Hallo,

    ich will mittels std::getline text aus einem Textfile lesen und Zeile für Zeile zusammenkleben. Das mache ich um sicher zu stellen dass in dem Text immer die selben Newlines vorkommen, nämlich "\r\n" und nicht z.B. nur "\n".

    Mein Code dafür:

    #include <iostream>
    #include <string>
    #include <fstream>
    
    int main()
    {
    	std::ifstream file("path to textfile");
    	std::string text = "";
    	std::string line;
    
    	while (std::getline(file, line))
    	{
    		text += line + "\r\n";
    	}
    	std::cout << text << std::endl;
    }
    

    Das klappt auch, allerdings gibt es ein Problem: Enthält das Textfile z.B. nur eine Zeile mit Text welche aber nicht mit einem Newline endet, wird dem ausgelesenen text trotzdem ein Newline angehängt.

    Also z.B. folgender Text:

    Textfile content
    

    enthält wie man sehen kann kein Newline. Die Methode die ich verwende fügt aber trotzdem eines hinzu.

    Wie kann man das sauber lösen? std::getline sagt mir ja nicht ob es ob die aktuelle line auch mit einem Newline endet oder nicht.



  • Eine "saubere" Textdatei enthält auch in der letzten Zeile ein Zeilenende. Wenn du also schon durchfegst, schadet es nicht, auch das zu korrigieren.



  • Stattnach jeder Zeile ein CRLF anzuhängen kannst du das ab der zweiten Zeile vor jeder neuen Zeile ein CRLF anhängen.
    Also statt
    Zeile CRLF
    Zeile CRLF
    Zeile CRLF
    machst du
    Zeile
    CRLF Zeile
    CRLF Zeile

    Damit wird an die letzte Zeile kein CRLF angehängt. Du kannst dir auch mal überlegen, ob du für den Zusammenbau lieber stringstream statt string benutzen möchtest.



  • manni66 schrieb:

    Eine "saubere" Textdatei enthält auch in der letzten Zeile ein Zeilenende.

    Sagt wer? Das Problem ist dass das eine Datei ist die vom Nutzer der Anwendung bereitgestellt wird. Mit der Datei kann konfiguriert werden, welchen Text der Startup-Bildschirm enthält. Wenn der User jetzt im Startup-Bildschirm kein Newline am Ende sehen will, soll das halt auch möglich sein.

    DocShoe schrieb:

    Stattnach jeder Zeile ein CRLF anzuhängen kannst du das ab der zweiten Zeile vor jeder neuen Zeile ein CRLF anhängen.
    Also statt
    Zeile CRLF
    Zeile CRLF
    Zeile CRLF
    machst du
    Zeile
    CRLF Zeile
    CRLF Zeile

    Damit wird an die letzte Zeile kein CRLF angehängt.

    Danke für den Vorschlag, aber das schlägt in so einem Fall fehl:

    Zeile1
    Zeile2
    Zeile3
    // Leere Zeile
    

    Hier ist die letzte Zeile (Zeile 4) leer (das Forum entfernt hier anscheinend leere Zeilen, deswegen den Kommentar wegdenken und stattdessen eine leere Zeile annehmen), Zeile 3 endet aber mit einem Newline. Mit diesem Code fehlt aber das abschließende Newline:

    #include <iostream>
    #include <string>
    #include <fstream>
    
    int main()
    {
        std::ifstream file("Pfad zur Datei");
        std::string line;
        std::string text = "";
    
        size_t cnt = 0;
    
        while (std::getline(file, line))
        {
            if (cnt == 0)
            {
                text += line;
            }
            else
            {
                text += "\r\n" + line;
            }
            ++cnt;
        }
        std::cout << text << std::endl;
    }
    

    In dem Fall endet jetzt text nicht mit einem Newline obwohl der Original-Text das tut.



  • Wenn die letzte Zeile kein Newline hat, dann ist file nach der letzten Zeile EOF.

    while(is >> line)
    {
        os << line;
        if(!is.eof())
            os << "\r\n";
    }
    


  • Caligulaminus schrieb:

    Wenn die letzte Zeile kein Newline hat, dann ist file nach der letzten Zeile EOF.

    Das scheint zu klappen, vielen Dank 👍


Anmelden zum Antworten