unterschied zwischen '\n' und endl bei einer Textdatei



  • hallo ich habe gerade einen Baum programmiert, einen text eingelesen und sortiert in eine neue Datei geschrieben mit der Methode.

    template<typename NODETYPE>
    ostream &Tree<NODETYPE>::write(ostream& os, TreeNode<NODETYPE> *&ptr )const
    {
    
    	os<<left<<setw(20)<<setfill('.')<<ptr->data<<right<<ptr->frequency<<'\n'; // anstelle von '\n' ein endl läuft Fehlerfrei
    	return os;
    
    }
    

    bei der Konsole hat er alles richtig sortiert ausgegeben so wie ich das wollte, aber im Text hat er es teilweise falsch sortiert ausgegeben.
    Nach längerem suchen ist mir aufgefallen das es an dem

    '\n'
    

    lag , als ich es durch

    endl
    

    erstetzt habe, hat er es sowohl in der Konsole wie auch in der Textdatei richtig sortiert und ausgegeben.

    Meine Frage ist nun: Warum?

    Ich persönlich hätte angenommen wenn er Falsch ausgibt dann sowohl in der Konsole als auch in der Textdatei.

    das hat mich echt ein wenig Verwundert, kann mir das jemand erklären?

    Grüße
    Joe



  • Das kommt darauf an womit Du die Textdatei ausgibst. Vergleiche mal Notepad und WordPad mit der "falsch" geschriebenen Datei 😉

    BTW: Ist die Datei mit dem Flag ios::binary geöffnet?



  • Hm, dann nutze ich die Gelegenheit und frage auch mal:

    Was ist denn der Unterschied, zwischen ios::binary und dem "normalen" Flags, wenn man ein endl oder \n reinschreibt?



  • Hallo,

    ich hatte es ohne binary, aber egal ob mit oder ohne, der Fehler bleibt bei

    '\n'
    

    bestehen.

    eingelesen wird meine Datei so.

    Tree<string> stringTree;
    	string stringValue;
    
    	fstream inFile("Text.txt", ios::binary |ios::in); 
    	while(inFile>>stringValue)
    	{
    		stringTree.insertNode(stringValue);
    	}
    	stringTree.inOrderTraversal();
    	inFile.close();
    

    und hier wird in die neue Datei geschrieben.

    fstream outFile("sortText.txt", ios::out|ios::ate|ios::app); 
    	if(!outFile)
    	{
    		cerr << "File ist nicht vorhanden!" << endl;
    		exit(1);
    	}
    	if ( ptr != 0 ) 
    	{
    		inOrderHelper( ptr->leftPtr ); // traverse left subtree  
    		write(outFile,ptr); // falsche ausgabe mit '\n' aber richtige Ausgabe mit endl
    		write(cout,ptr);    // korrekte ausgabe auch mit '\n'
    		inOrderHelper( ptr->rightPtr ); // traverse right subtree
    	} // end if
    

    ich habe jetzt nicht ganz verstanden wie du das mit WordPad meinst, weil die Datei ist ja beschrieben und die Wörter stehen schon drin.
    Es ist ja egal mit was ich das jetzt öffne, oder hab ich da jetzt was fehlinterpretiert?

    Gruss & danke
    Joe



  • also '\n' ist ein Unix-Zeilenende, da gibt es ab und zu Probleme bei Notepad, soweit ich mich erinnere^^ Das meinte er wohl.

    Unter Windows ist glaube ich '\r\n' die Sequenz für einen Zeilenumbruch^^



  • Die Sache ist, dass es unter verschiedenen Betriebssystemen verschiedene Zeilenenden gibt. Unter Windows ist das "\015\012" (das ist oktal), oder "Carriage-Return Linefeed", in C "\r\n". Unter anderen Systemen reicht aber ein "\012" aka "\n".

    Wenn man jetzt unter Windows binär eine Datei schreibt, die am Ende der Zeilen nur "\n" hat, fehlt natürlich was. Aber viele Editoren (so auch Wordpad, und offenbar auch die Konsole) können auch solche UNIX-Zeilen korrekt anzeigen, Notepad jedoch nicht. Deshalb sieht es hier aus als wäre die komplette Datei in einer Zeile.

    Jetzt war ich jedoch der Ansicht, dass wenn man "\n" im Textmodus in eine Datei schreibt, die Standardbibliothek automatisch das für das System passende daraus macht. Deshalb habe ich nach dem Binärmodus gefragt (und bin nun etwas verunsichert, was diese Ansicht angeht). endl ist jedoch immer ein zur Plattform passendes Zeilenende, deshalb klappt es damit wohl.



  • ok dann sag ich mal danke für die Antworten.



  • Du solltest also immer Textdateien im Textmodus (also ohne ios::binary) sowohl lesen als auch schreiben. Und 'endl' ist besser als '\n', da unter Windows die Standard-Library die richtige Zeilenendung "\r\n" erzeugt.
    Du kannst es ja mal selber mit "\r\n" ausprobieren?



  • Th schrieb:

    Du solltest also immer Textdateien im Textmodus (also ohne ios::binary) sowohl lesen als auch schreiben. Und 'endl' ist besser als '\n', da unter Windows die Standard-Library die richtige Zeilenendung "\r\n" erzeugt.
    Du kannst es ja mal selber mit "\r\n" ausprobieren?

    Also diese Begründung ist Käse - im Textmodus kümmert sich der Stream (je nach verwendetem System) selbst darum, die \n umzurechnen zu einem \r\n und zurück. Und endl schreibt einfach nur ein '\n' und flusht anschließend den Stream (was bewirkt, daß die zuletzt ausgegebenen Daten tatsächlich auf der Festplatte landen).



  • Hallo,

    wichtig ist noch dass endl ein flush auf den stream macht.



  • CStoll, ja hast recht, mein Satz klingt falsch.
    Ich meinte, man sollte '\n' nicht einfach so im Binärmodus ausgeben.
    Nichtsdestotrotz halte ich persönlich 'endl' immer noch besser als '\n' zu schreiben...


Anmelden zum Antworten