InfoCenter

Zeilenumbruch

Es gibt mehrere unterschiedliche Möglichkeiten, wie Zeilenumbrüche innerhalb von Textdateien realisiert sein können. In diesem Artikel möchten wir uns zunächst diese verschiedenen Arten von Zeilenumbruchtypen ansehen und anschließend sowohl auf die Probleme die durch diese Variabilität auftreten können eingehen als auch Lösungen und einige Anwendungsbeispiele für diese Probleme anbieten.

Grundsätzlich gibt es drei verschiedene Kategorien, in die wir die verschiedenen Arten von Zeilenumbruchtypen einordnen können: Zeichenbasierte Zeilenumbrüche, Zeilenumbrüche durch die Definition einer fixen Zeilenlänge sowie durch eine Auszeichnungssprache (markup) realisierte Zeilenumbrüche. In den folgenden Abschnitten möchten wir als Einführung in die Thematik als erstes diese drei Kategorien mitsamt ihrer prominentesten Vertreter gegenüberstellen.

Zeichenbasierte Zeilenumbruchtypen

Die meisten Plain-Textdateien verwenden zur Auszeichnung ihrer Zeilenumbrüche bestimmte zuvor definierte Zeichen beziehungsweise Bytes. Wenn das Programm, das eine solche Textdatei lesen, verarbeiten oder anzeigen soll, diese Zeichen kennt, weiß es, dass diese Zeichen nicht als Buchstabe angezeigt werden sollen sondern als (unsichtbare) Zeilenumbrüche interpretiert werden können.

Leicht umzusetzen wäre diese Vorgehensweise, wenn man sich im Laufe der Zeit auf ein einziges bestimmtes Zeichen für einen Zeilenumbruch geeinigt hätte. Dadurch dass die verschiedenen Systeme allerdings historisch gewachsen sind, ist dies bis heute nicht der Fall. Je nach Betriebssystem können daher andere Zeichen beziehungsweise Bytes für einen Zeilenumbruch verwendet werden.

Zeichen und Codepoints für Zeilenumbrüche und deren Verwendung

Die folgende Tabelle gibt eine Übersicht über die verschiedenen Zeichen sowie Zeichenkombinationen für Zeilenumbrüche und die gebräuchlichsten Systeme, die die jeweilige Art von Zeilenumbruch nutzen:

AbkürzungCode (Hex/Dez)ZeichensatzSystem/Verwendung
CR LF0D 0A / 13 10ASCIIWindows, MS-DOS, OS/2, Symbian OS, Palm OS, Atari TOS, CP/M, MP/M, RT-11, Amstrad CPC, DEC TOPS-10 sowie die meisten anderen frühen Nicht-Unix- und Nicht-IBM-Betriebssysteme
LF0A / 10ASCIILine Feed / Zeilenvorschub - Unix und Unix-ähnliche Systeme (Linux, macOS, Mac OS X, Android, BSD, AIX, Xenix und so weiter), Amiga, AmigaOS, QNX, Multics, BeOS, RISC OS und andere am POSIX-Standard orientierte Systeme
CR0D / 13ASCIICarriage Return / Wagenrücklauf - Mac OS (Classic) bis Version 9, Apple II, Lisa OS, Commodore 64 (C64), Commodore 128 (C128), Acorn BBC, ZX Spectrum, TRS-80, Oberon, HP Series 80, MIT Lisp Machine, OS-9
RS1E / 30ASCIIRecord Separator / Datensatztrenner - QNX (vor der POSIX Implementierung mit Version 4)
EOL9B / 155ATASCIIEnd Of Line - Atari 8-Bit Computer
NL15 / 21EBCDICNew Line - IBM Mainframe Systems wie z/OS (OS/390) oder IBM i (i5/OS, OS/400)
LF25 / 37EBCDICLine Feed - EBCDIC-Zeichen für ASCIIs 0A
RNL06 / 06EBCDICRequire New Line (ab 2007)
 76 / 118ZX80/ZX81Sinclair Research Home Computers Linebreak
VTU+000BUnicodeVertical Tab / Vertikaler Tab
FFU+000CUnicodeForm Feed / Seitenvorschub
NELU+0085UnicodeNext Line / Nächste Zeile
LSU+2028UnicodeLine Separator / Zeilentrenner
PSU+2029UnicodeParagraph Separator / Absatztrenner

Der weltweit am weitesten verbreitete und am häufigsten genutzte Zeichensatz ist ASCII (American Standard Code for Information Interchange) beziehungsweise der auf ASCII aufbauende Unicode-Standard. Diesem Zeichensatz entstammen auch die beiden gebräuchlichsten und am weitesten verbreiteten Zeilenumbruchtypen: Der Unix-Zeilenumbruch LF sowie der Windows-Zeilenumbruch CR LF.

Unix und das aktuelle macOS von Apple nutzen als Zeilenumbruch den Unicode-Codepoint U+000D während ältere Apple-Systeme U+000A verwenden. Windows und MS-DOS nutzen gleich beide dieser Zeichen hintereinander in der Reihenfolge 0D0A. Neben diesen drei Zeichen und Zeichenfolgen fordert der Unicode-Standard auch die am Ende der Tabelle dargestellten Code-Points U+000B (Vertical Tab VT, vertikaler Tabulator), U+000C (Form Feed FF, Seitenvorschub / Seitenumbruch = neue Seite), U+0085 (Next Line NEL, Nächste Zeile), U+2028 (Line Separator LS, Zeilentrenner) sowie U+2029 (Paragraph Separator PS, Absatztrenner) als Zeilenumbruch zu interpretieren. Dies tun bis heute jedoch nur wenige Programme.

Einer der bekanntesten Zeichensätze außerhalb der ASCII-Welt ist der von IBM für seine Großrechner entwickelte 8-Bit-Zeichensatz EBCDIC (Extended Binary Coded Decimal Interchange Code). In diesem Zeichensatz wird das hexadezimale Zeichen 15 (dezimal 21) für einen Zeilenumbruch verwendet, das die Funktionen von CR und LF kombiniert. Zusätzlich enthält EBCDIC aber auch noch die ASCII-typischen Zeichen CR und LF (wenn auch zweiteres unter einem anderen Zeichencode) sowie ab 2007 das weitere Zeichen RNL (Required New Line - "Neue Zeile benötigt"), das für die Kodierung eines bedingten automatischen Zeilenumbruchs verwendet werden kann.

Weniger verbreitet beziehungsweise nur von historischer Relevanz sind die Zeilenumbrüche EOL (End Of Line), der hauptsächlich in den 1980er genutzten Atari 8-Bit Computer aus dem von Atari genutzten 8-Bit-Zeichensatz ATASCII (ATARI Standard Code for Information Interchange), die ebenfalls in den 1980er Jahren von Sinclair Research Ltd für seine Computer verwendeten Zeilenumbrüche aus den Zeichensätzen ZX80 und ZX81 sowie der Zeilenumbruch RS (Record Separator), der bis zum Erscheinen der Version 4.0 im Jahre 1990 vom Betriebsystem QNX genutzt wurde. Einige historische Betriebsysteme definierten Zeilenumbrüche sogar auf Bit-Ebene: Betriebssysteme der CDC 6000 Serie aus den 1960er Jahren, zu einer Zeit als Speicher noch teuer war, definierten ihren Zeilenumbruch beispielsweise als zwei oder mehr mit Null-Bits gefüllte 6-Bit-Zeichen am Ende eines 60-Bit-Words.

Wieso besteht der Windows-Zeilenumbruch aus zwei Zeichen?

Dass Windows, MS-DOS sowie die meisten anderen frühen Nicht-Unix- und Nicht-IBM-Betriebssysteme ihren Zeilenumbruch im Gegensatz zu den genannten anderen Betriebssystemen durch gleich zwei Zeichen definieren, hat historische Gründe und ist zurückzuführen auf die Vorgehensweise von Schreibmaschinen und alten Druckgeräten:

Auf einer Schreibmaschine wird der Umbruch einer Zeile nämlich ebenfalls durch zwei voneinander unterscheidbaren Aktionen durchgeführt: Die Schreibstelle rückt einerseits zurück an den Anfang der Zeile (Wagenrücklauf) und die Schreibstelle geht andererseits eine Zeile nach unten, zum Beispiel indem das zu bedruckende Papier durch drehen der Walze weiter geschoben wird (Zeilenvorschub). Ein vollständiger "Zeilenumbruch" setzt sich gemäß dieser Logik demnach aus einer Kombination dieser beiden Aktionen zusammen. Als in den 1960er Jahren die Systeme für Zeichensätze für Computer entwickelt wurden, definierte man in diesen Zeichensätzen sowohl separate Steuerzeichen für den Wagenrücklauf als auch für den Zeilenvorschub, um die damalige Steuerung von Druckern in der gleichen Weise abbilden und realisieren zu können. Diese Historie schlägt sich bis zu den aktuellsten Windows-Versionen von heute nieder.

Der Wagenrücklauf (auf Englisch "Carriage Return" = CR) bekam im damaligen ASCII-Zeichensatz den dezimalen Code 13 (hexadezimal 0D) und wird mit "CR" abgekürzt, der Zeilenvorschub (auf Englisch "Line Feed" = LF) bekam den dezimalen Code 10 (hexadezimal 0A) und wird "LF" abgekürzt. Beide dieser Zeichen sind auch heute noch im aktuellen Unicode-Standard unter den gleichen numerischen Codepoints zu finden.

Manche Systeme nutzten die Unterscheidung zwischen CR und LF auch für diverse Texteffekte. Verwendete man bei der Druckersteuerung nur CR ohne LF ließ sich dadurch ein Wagenrücklauf ohne Zeilenvorschub realisieren. Die Schreibstelle konnte auf diese Weise an den Beginn einer bereits gedruckten Zeile gelangen und damit den vorhandenen Text mit anderen Zeichen überdrucken. So ließ sich zum Beispiel Text unterstreichen, durchstreichen oder fett schreiben. Auch diakritische Zeichen außerhalb des eigentlich verwendeten Zeichensatzes wurden auf diese Weise durch Überdruck beziehungsweise Kombination verschiedener Zeichen möglich. Ähnlich kann das im Unicode-Standard definierte Steuerzeichen RI (Reverse Line Feed = "umgekehrter Zeilenvorschub") mit dem Unicode-Codepoint U+008D verwendet werden.

Unicode, ASCII, EBCDIC, HTML-Entities und Escape-Sequenzen

Wie wir im letzten Abschnitt gesehen haben, gibt es zwischen den einzelnen Zeichensätzen neben vielen Gemeinsamkeiten auch gewisse Unterschiede. Aus diesem Grund möchten wir die betreffenden Zeichen in der nächsten Tabelle noch einmal gegenüberstellen:

ZeichenUnicode Code PointASCIIEBCDICHTML EntityEscape Sequenz
CRU+000D0D130D13

 \r
LFU+000A0A102537

\n
CR LF-0D 0A13 100D 2513 37--\r\n
NEL/NLU+0085-1521……\u0085
VTU+000B0B110B11\v
FFU+000C0C120C12\f
LSU+2028--

\u2028
PSU+2029--

\u2029

Da der Unicode-Standard aus Kompatibilitätsgründen alle Zeichen aus dem ASCII-Zeichensatz mit identischen Codepoints als Block "Basis-Lateinisch" vollständig übernommen hat, sind alle Zeichen für Zeilenumbrüche aus dem ASCII-Zeichensatz wie der Zeilenvorschub LF, der Wagenrücklauf CR, der vertikale Tab VT sowie der Seitenvorschub FF sowohl im ASCII-Zeichensatz als genauso auch als gleichlautende Unicode-Codepoints definiert.

Zusätzlich definiert der Unicode-Standard noch die Codepoints U+0085, U+2028 und U+2029 als weitere Zeilenumbrüche, die im ASCII-Zeichensatz nicht enthalten sind. Von diesen echten Zeilenumbrüchen zu unterscheiden sind die Unicode-Codepoints U+2424 (Symbol for Newline), U+23CE (Return-Symbol), U+240D (Symbol for Carriage Return) sowie U+240A (Symbol for Line Feed), die zwar selber keinen Zeilenumbruch erzeugen, mit denen sich jedoch für den Nutzer sichtbare Glyphs erzeugen lassen, um die sonst unsichtbaren Zeilenumbruch-Zeichen zu visualisieren.

Auch der hauptsächlich von IBM Mainfraime Systems (Großrechnern) genutzte EBCDIC-Zeichensatz weist viele Parallelen zu ASCII auf. Auch wenn der Standard-EBCDIC-Zeilenumbruch das Zeichen NEL ist (hexadezimaler Code 15 / dezimaler Code 21), das selber keine ASCII-Entsprechung hat, definiert auch EBCDIC Codepoints für die Zeichen CR, LF, VT und FF. Nur LF ist von diesen vier Zeichen unter einem anderen, von ASCII abweichenden Codepoint in EBCDIC definiert (25/37 statt 0A/10).

Das zu EBCDIC-NL äquivalente Unicode-Zeichen ist NEL (Next Line) und hat den Unicode-Codepoint U+0085. Dieses Zeichen wurde auch deswegen zusätzlich zu CR und LF im Unicode-Standard definiert, um eine bidirektionale Konvertierung aus und in alle anderen Kodierungen zu ermöglichen. Hätten wir nur die Zeichen CR und LF im Unicode-Standard zur Verfügung, wäre dies nämlich nicht möglich: Wenn wir zum Beispiel einen EBCDIC-Text nach Unicode und wieder zurück konvertieren wollten, könnten wir in diesem Fall bei der Hinkonvertierung zunächst alle NEL-Zeilenumbrüche entweder in LF oder CR LF ändern. Bei der Rückkonvertierung kämen wir allerdings in eine Uneindeutigkeit, da EBCDIC einen Unterschied zwischen CR, LF und NL macht und es deswegen nicht mehr eindeutig wäre, ob unsere LF- und CR-Zeichen schon vorher LF und CR waren (und damit beibehalten werden müssten) oder sie ursprünglich ein NL waren (das rück-konvertiert werden müsste). Dadurch dass uns aber auch im Unicode-Standard die drei verschiedenen Zeichen CR, LF und NEL zur Verfügung stehen, ist eine Transformation ohne Informationsverlust möglich.

Weiterhin zeigt die Tabelle in ihren letzten beiden Spalten die HTML-Entities sowie die Escape-Sequenzen der einzelnen Zeichen. Die HTML-Entities können dafür verwendet werden, die jeweiligen Zeichen in einen HTML-Quelltext einzufügen. Die Tabelle zeigt die HTML-Entities sowohl in ihrer hexadezimalen als auch in ihrer dezimalen Schreibweise. Diese beiden Varianten führen zu dem gleichen Ergebnis und können daher austauschbar verwendet werden. Für das LF-Zeichen kann darüber hinaus die HTML-Entity 
 verwendet werden. In ähnlicher Weise sind auch die Escape-Sequenzen aus der letzten Spalte Platzhalter der genannten Zeichen. Die Escape-Sequenzen lassen sich zum Beispiel in regulären Ausdrücken oder in einigen Programmiersprachen als Alias beziehungsweise zum Einfügen der entsprechenden Zeilenumbruchzeichen nutzen. Mehr dazu im Abschnitt über Zeilenumbrüche im Programmcode.

Auf ASCII basierende 8-Bit-Kodierungen wie die Windows Codepages oder die Latin-Zeichensätze sind in der Tabelle nicht aufgeführt, da auch diese Zeichensätze alle ASCII-Zeichen 1:1 übernommen haben und daher der Spalte "ASCII" in der Tabelle entsprechen.

Nur der Vollständigkeit halber sollte weiterhin noch erwähnt werden, dass es neben dem gebräuchlichen und am häufigsten genutzten Unicode-Standard, der seine ersten Codepoints aus dem ASCII-Zeichensatz übernommen hat, auch einen alternativen Unicode-Standard namens UTF-EBCDIC gibt, der stattdessen weitestgehend auf dem EBCDIC-Zeichensatz aufbaut.

Byte-Repräsentationen in verschiedenen Kodierungen

Abhängig von der verwendeten Kodierung resultieren die genannten Unicode-Codepoints in unterschiedlichen Bytes innerhalb einer gespeicherten Datei. Eine Übersicht über die Bytefolgen der verschiedenen Zeilenumbruchtypen in den Kodierungen ASCII, UTF-7, UTF-8, UTF-16 Litte Endian und Big Endian sowie UTF-32 Litte Endian und Big Endian gibt die folgende Tabelle:

ZeichenUnicode Code PointASCIIUTF‑7UTF‑8UTF‑16 LEUTF‑16 BEUTF‑32 LEUTF‑32 BE
CRU+000D0D0DOD0D 0000 0D0D 00 00 0000 00 00 0D
LFU+000A0A0A0A0A 0000 0A0A 00 00 0000 00 00 0A
CR LF-0D 0A0D 0A0D 0A0D 00 0A 0000 0D 00 0A0D 00 00 00 0A 00 00 0000 00 00 0D 00 00 00 0A
NEL/NLU+0085-2B 41 49 55C2 8585 0000 8585 00 00 0000 00 00 85
VTU+000B0B2B 41 41 730B0B 0000 0B0B 00 00 0000 00 00 0B
FFU+000C0C2B 41 41 770C0C 0000 0C0C 00 00 0000 00 00 0C
LSU+2028-2B 49 43 67E2 80 A828 2020 2828 20 00 0000 00 20 28
PSU+2029-2B 49 43 6BE2 80 A929 2020 2929 20 00 0000 00 20 29

Typische 8-Bit-Kodierungen, die auf ASCII aufbauen, wie zum Beispiel die Windows-Codepages oder die Latin-Zeichensätze sind in der Tabelle nicht gesondert aufgeführt. Diese Kodierungen nutzen die selben Bytes wie ASCII, die entsprechend in der ASCII-Spalte zu finden sind. Auch viele andere ANSI-Codepages und Zeichensätze folgen dieser Konvention.

Wichtig sind die in dieser Tabelle aufgeführten Byte-Repräsentationen unter anderem für die Erkennung des Zeilenumbruchtyps von Dateien, der wir uns im Abschnitt über das Erkennen des Zeilenumbruchtyps einer Datei widmen.

Zeilenumbruchzeichen als Zeilentrenner oder als Markierung des Zeilenendes

Zeichen für Zeilenumbrüche lassen sich in zwei verschiedenen Weisen interpretieren, die beide ihre Fürsprecher und Vertreter haben: ein Zeilenumbruchzeichen kann entweder als Trennzeichen zwischen zwei Zeilen angesehen werden oder als Markierung eines Zeilenendes.

Schauen wir uns dazu das folgende Beispiel an, in dem "N" für das Zeilenumbruchzeichen steht:

abcNdefN

Den Inhalt einer solchen Datei könnten wir auf zwei verschiedene Weisen interpretieren:

Es gibt sowohl Programme, die Zeilenumbruchzeichen als Separator ansehen als auch andere Programme, die Zeilenumbruchzeichen als Terminator interpretieren. Die Probleme, die daraus resultieren, liegen auf der Hand: Programme, die das Umbruchzeichen als Trennzeichen ansehen, interpretieren möglicherweise eine (leere) Zeile zu viel; Programme, die das Umbruchzeichen dagegen als Marker für das Zeilenende ansehen, haben möglicherweise Probleme, die letzte Zeile einer Datei zu lesen.

Eingabe von Zeilenumbruch-Zeichen

Der Systemzeilenumbruch lässt sich in der Regel am einfachsten mit der Enter-Taste eingeben. Eine Ausnahme ergibt sich für den Fall, dass die Eingabe innerhalb eines Editors erfolgt, der andere Zeilenumbruchtypen versteht und in dem entweder gerade an einer Datei mit systemfremdem Zeilenumbruchtyp gearbeitet wird oder die Einstellungen dieses Editors (oder eines anderen Programms) einen entsprechenden anderen Zeilenumbruchtyp vorsehen.

Die Eingabe der anderen Zeilenumbruchtypen ist etwas schwieriger: Einige Systeme und Texteditoren erlauben die Tastenkombination STRG + J für die Eingabe des LF-Zeichens. Weitere gebräuchliche Tastenkombinationen sind STRG + M für CR sowie STRG + K für VT (auf diese Weise kommt auch die Anzeige von ^M für CR zustande). Interpretieren wir CR und LF als Wagenrücklauf und Zeilenvorschub können wir dies über die Tasten Pos1 und Pfeil-Runter realisieren.

Innerhalb von HTML-Quelltext können die Zeilenumbruch-Zeichen darüber hinaus über ihre HTML-Entities eingefügt werden, die in der Tabelle im Abschnitt "Unicode, ASCII, EBCDIC, HTML-Entities und Escape-Sequenzen" aufgelistet sind. Weiterhin können wir die Zeichen mit der Tastenkombination ALT + Codepoint des Zeichens über das Num-Tastenfeld der Tastatur eingeben und in einigen Kontexten wie zum Beispiel in regulären Ausdrücken oder in vielen Programmiersprachen die Escape-Sequenzen der Zeichen nutzen, die ebenfalls in der genannten Tabelle für jedes der Zeichen aufgeführt sind. Mehr zu letzterem im Abschnitt über Zeilenumbrüche im Quellcode verschiedener Programmiersprachen.

Zeilenumbrüche durch Definition einer festen Zeilenlänge

Im Gegensatz zu den auf bestimmten Zeichendefinitionen basierenden Zeilenumbruchtypen, die im letzten Abschnitt vorgestellt wurden, kommen Textdateien mit einer fixen Zeilenlänge ganz ohne die Definition eines oder mehrerer Zeichen für einen Zeilenumbruch aus. Stattdessen basiert jede Zeile einer solchen Datei auf einer zunächst frei wählbaren Zeilenlänge, die jedoch innerhalb der Datei konstant gehalten wird. In der Datei selber werden dann alle Zeilen einfach hintereinander weg geschrieben und gegebenenfalls durch ein geeignetes Füllzeichen auf die geforderte Länge gebracht.

Der Inhalt einer solchen Datei (hier beispielhaft mit einer festen Zeilenlänge von vier Zeichen) kann dann zum Beispiel so aussehen:

ABCDABC ABCD

Ein Programm, das die für die Datei verwendete Zeilenlänge kennt und darstellen kann, kann diesen Inhalt dann folgendermaßen interpretieren:

ABCD
ABC
ABCD

Da die zweite Zeile nur drei Zeichen enthält, haben wir hier ein Leerzeichen als Füllzeichen verwendet. Hätten wir das nicht getan, wäre das "A" aus der dritten Zeile an das Ende der zweiten Zeile gerutscht.

Verbreitung und Anwendungsbereiche

Dateien mit einer festen Zeilenlänge sind deutlich weniger weit verbreitet als Dateien, die ihre Zeilenumbrüche mit einem festgelegten Zeichen für einen Umbruch realisieren. Der Hauptgrund, der gegen die Verwendung einer festen Zeilenlänge spricht, ist die mangelnde Flexibilität. Schließlich haben die wenigsten Texte in jeder Zeile gleich viele Zeichen.

Dennoch gibt es einige nützliche Anwendungsbereiche für solche Dateien, zum Beispiel im Falle von CSV-Daten oder anderen Datensätzen, deren Werte in jeder Zeile alle die gleiche Länge haben, so dass zusätzliche Zeichen für Zeilenumbrüche keinen weiteren Informationsgewinn für die Interpretation derartiger Dateien darstellen würden, sodass diese Zeichen entsprechend eingespart werden können (insbesondere in Anwendungen oder Umgebungen in denen Speicher gespart werden muss).

Feste Zeilenlänge als Systemzeilenumbruch

Als Systemzeilenumbruch wurde die Feste Zeilenlänge lediglich auf einigen der ersten Großrechner genutzt. Üblich auf solchen Systemen waren damals meist feste Zeilenlängen von 72 oder 80 Zeichen. Diese Anzahl war den davor verwendeten Lochkarten nachempfunden, die üblicherweise auch 80 Spalten pro Karte umfassten, von denen die Spalten 73 bis 80 häufig für Sequenznummern verwendet wurden. Einige dieser Systeme kodierten Zeilen mit mehr als 80 Zeichen indem ein Carriage-Zeichen wie # als erstes Zeichen an den Anfang der nächsten zu verknüpfenden Zeile gestellt wurde.

Ebenfalls ohne Zeichen für einen Zeilenumbruch kommen auf Records basierende Dateisysteme aus, wie sie zum Beispiel von den Betriebssystemen OpenVMS, RSX-11 oder diversen neueren Großrechnern genutzt werden. Solche Systeme speichern Textdateien als je ein Record pro Zeile. Jeder dieser Records enthält ein Längenfeld am Zeilenanfang, in dem individuell die Länge der jeweiligen Zeile gespeichert ist. Dadurch ist kein zusätzlicher Zeilenbegrenzer in Form eines Steuerzeichens notwendig, da das lesende Programm durch diese Information bereits weiß, nach wie vielen Zeichen die Zeile endet beziehungsweise wie viele Zeichen eingelesen werden müssen, um eine Zeile zu lesen. Auch wenn die Speicherung auf diese Weise ohne Zeichen für einen Zeilenumbruch auskommt, sind die verwendeten Record Management Systeme in der Regel dazu fähig, einem anfragenden Programm die angefragten Zeilen nach Bedarf auch mit einem Zeilentrennerzeichen zu übergeben.

Zeilenumbrüche im HTML-Quelltext und anderen Auszeichnungssprachen

Neben den zeichenbasierten Zeilenumbruchtypen und den Zeilenumbrüchen durch Definition einer festen Zeilenlänge, die wir uns in den letzten beiden Abschnitten angesehen haben, gibt es die weitere Möglichkeit, Zeilenumbrüche durch eine Auszeichnungssprache (in Englisch "markup") zu realisieren.

Zeilenumbrüche im HTML-Quelltext

Zu den bekanntesten Vertretern der Auszeichnungssprachen zählt der auf XML basierende Quelltext von HTML, die Basis von Internetseiten, wie wir sie heute kennen. Die Realisierung von Zeilenumbrüchen im HTML-Quelltext und in anderen ähnlichen Auszeichnungssprachen stellt insofern eine Besonderheit dar, da Zeilenumbrüche dabei auf zwei verschiedenen Ebenen auftreten können: Im Quelltext selber können beliebige zeichenbasierte Zeilenumbrüche wie CRLF oder LF enthalten sein, die aber im Verborgenen bleiben, da die letztendliche Darstellung von Zeilenumbrüchen auf der später sichtbaren Internetseite im Browser allein auf der Grundlage der textbasierten HTML-Tags und anderer Formatierungen wie CSS-Stylesheets beruht.

Um dies zu verdeutlichen, möchten wir uns zwei HTML-Quelltexte als Beispiel ansehen. Einerseits den folgenden HTML-Quelltext:

<h1>Überschrift</h1><p>Erster Absatz</p><p>Zweiter<br>Absatz</p>

Andererseits diesen Quelltext:

<h1>Überschrift</h1>
<p>Erster Absatz</p>
<p>Zweiter<br>
Absatz</p>

Wie wir sehen enthält das erste Beispiel keinerlei "sichtbare" Zeilenumbrüche, während im zweiten Beispiel hinter jedem Sinnabschnitt sowie innerhalb des zweiten Absatzes ein Zeilenumbruch gesetzt ist. Dennoch führen beide Quelltexte zu exakt derselben Darstellung im Browser. Für die Interpretation des Quelltextes spielt so genannter Whitespace wie zusätzliche Leerzeichen, Tabs oder eben auch Zeilenumbrüche nämlich keine Rolle.

Entscheidend ist in diesem Beispiel-Quelltext nur, dass wir einen Text in einen h1-Tag ("Überschrift 1" von englisch "heading") gesetzt haben und zwei weitere Texte in einen p-Tag (Absatz von englisch "paragraph"). Standardmäßig (man kann dieses Verhalten auch überschreiben) werden diese Tags beide so interpretiert, dass hinter ihnen ein Zeilenumbruch in Form eines Absatzes eingefügt wird. Das gleiche gilt auch für Tags wie h2 (Überschrift 2), h3 (Überschrift 3), li (Listenelemente) oder dem klassischen HTML-Zeilenumbruch br (einfacher Umbruch von englisch "break"), mit dem wir den zweiten Absatz umgebrochen haben. Durch andere Tags wie zum Beispiel fomatierenden Tags wie b (bold / fett) oder i (italic / kursiv) werden in der Darstellung keine automatischen Umbrüche eingefügt.

Klassische, nicht auf Tags basierende Zeilenumbrüche im Quelltext können dagegen unabhängig von der Darstellung im Browser verwendet werden, zum Beispiel um den Quelltext zu gliedern und besser lesbar zu machen. Dabei können diese später im Browser unsichtbaren Zeilenumbrüche sowohl in Form von zeichenbasierten Zeilenumbrüchen verwendet werden als auch zum Beispiel über sogenannte HTML-Entities eingefügt werden, die im Abschnitt über HTML-Entities aufgelistet sind.

Verhalten durch den pre-Tag überschreiben

Überschreiben lässt sich dieses Verhalten der unsichtbaren zeichenbasierten Zeilenumbrüche im Quelltext durch den HTML-Tag "pre" sowie durch das CSS-Style-Attribute "white-space:pre". Die Zeilenumbrüche und sonstiger Whitespace wie Leerzeichen von Quelltext, der sich innerhalb eines pre-Tags oder innerhalb von Tags mit der CSS-Eigenschaft "white-space" mit dem Wert "pre" befinden, werden dadurch als solche im Browser ausgegeben:

<pre>Zeile 1
Zeile 2</pre>
<span style="white-space: pre">Zeile 3
Zeile 4</span>

Dieser Quelltext erzeugt im Browser vier umgebrochene Zeilen obwohl die Zeilenumbrüche lediglich mittels normalerweise unsichtbarem "Whitespace" in den Quelltext geschrieben wurden. Der Zeilenumbruch zwischen der ersten und der zweiten Zeile wird durch den pre-Tag erzeugt, der Zeilenumbruch zwischen der dritten und vierten Zeile durch die CSS-Eigenschaft des umschließenden span-Elements.

Zeilenumbrüche in LaTeX, Markdown, RTF, Creole, PostScript, BBCode und AsciiDoc

Andere gebräuchliche Auszeichnungssprachen sind zum Beispiel LaTeX, Markdown, RTF, Creole und PostScript, in denen jeweils eine andere Syntax zur Auszeichnung von Zeilenumbrüchen verwendet wird:

In Auszeichnungssprachen wie BBCode oder AsciiDoc werden dagegen trotz der Möglichkeit anderer Auszeichnungen (wie zum Beispiel "[b]wort[/b]" beziehungsweise "*wort*" für fetten Text) Zeilenumbrüche aus dem Quelltext genauso auch in das Ergebnis übernommen. In diesen Auszeichnungssprachen wird insofern der zeichenbasierte Zeilenumbruch (ähnlich wie in Markdown) selber als Markup verwendet.

Voraussetzungen für die Nutzung von Auszeichnungssprachen

Voraussetzung für die Nutzung von Auszeichnungssprachen wie HTML, TeX / LateX, Markdown, RTF, Creole, PostScript, BBCode oder AsciiDoc ist natürlich, dass die verwendeten Auszeichnungen, Befehle und Tags bekannt sein müssen. Ohne zu wissen, wie bestimmtes Markup gemeint ist, verwendet oder interpretiert werden soll, ist eine Darstellung nicht möglich.

Zeilenumbrüche im Quellcode verschiedenener Programmiersprachen

Auch im Quellcode von Programmierungen sind wir mit dem Problem konfrontiert, dass wir - ähnlich wie beim HTML-Quelltext - einen Unterschied machen müssen zwischen dem Quellcode selber sowie dem, was später real vom ausgeführten und möglicherweise kompilierten Programm angezeigt werden soll. Dabei gilt es den Spagat zu meistern zwischen einem möglichst gut durch Menschen lesbaren Code, der sich jedoch nicht negativ auf das Programm auswirken darf.

Gelöst wurde dieser Spagat auch hier, indem viele Programmiersprachen strikt zwischen den Zeilenumbrüchen im Quellcode und den Zeilenumbrüchen, die später das Programm ausgibt, unterscheiden: Im Quellcode können in der Regel je nach Betriebssystem die üblichen zeichenbasierten Zeilenumbrüche verwendet werden, während für die im Programm ausgegebenen Zeilenumbrüche eine Auszeichnungssprache existiert, die sich von Programmiersprache zu Programmiersprache unterscheiden kann. Einige Beispiele dafür sind in der folgenden Tabelle gelistet:

SpracheExpliziter ZeilenumbruchSystemzeilenumbruch
Cchar s[] = "-\r\x0A-";char s[] = "\n";
C++std::string s = "-\r\x0A-";std::string s = "\n";
C#string s = "-\r\n-";string s = Environment.NewLine;
JavaString s = "-\r\n-";String s = System.lineSeparator();
String s = "-%n-";
JavaScript / TypeScriptvar s = "-\n-";
Delphivar s: string;
s := '-' + #13#10 + '-';
var s: string;
s := sLineBreak;
Lazarus / FreePascalvar s: string;
s := '-' + #13#10 + '-';
var s: string;
s := LineEnding;
PHP$s = "-\r\n-";$s = PHP_EOL;
Pythons = "-\r\n-"s = os.linesep
Perlmy $s = "-\r\x0A-"; my $s = "\n";
Haskell"-\CR\LF-" :: [Char]"\n" :: [Char]
Visual BasicDim s1 As String = "-" & vbCrLf & "-";
Dim s2 As String = "-" & vbCr & "-";
Dim s3 As String = "-" & vbLf & "-";
Dim s1 As String = System.Environment.NewLine;
Dim s2 As String = vbNewLine; (deprecated)
SQLUPDATE tab SET col = '-' + CHAR(13) + CHAR(10) + '-'; 

Wie die Tabelle zeigt, können wir in den meisten Programmiersprachen zwei verschiedene Herangehensweisen nutzen, um einen Zeilenumbruch einzufügen:

In den nächsten beiden Abschnitten möchten wir näher auf beide Varianten und deren Fallstricke eingehen.

Expliziter Zeilenumbruch

In vielen Programmiersprachen wie C, C++, C#, Java, PHP, Python, Perl oder Haskell können die im Abschnitt "Zeichenbasierte Zeilenumbruchtypen" vorgestellten Escape-Sequenzen wie \r und \n für die Einfügung eines Zeilenumbruchs in einen String verwendet werden. Grundsätzlich steht dabei \r für einen Carriage Return (CR, U+000D, Wagenrücklauf) und \n für einen Line Feed (LF, U+000A, Zeilenvorschub), wodurch sich die Zeilenumbrüche für die verschiedenen Systeme erzeugen lassen.

Je nach Programmiersprache sind bei der Verwendung von \r und \n jedoch noch die folgenden Aspekte und Besonderheiten zu beachten:

Etwas anders verhält es sich in Delphi, Lazarus, Visual Basic und SQL. Statt den Escape-Sequenzen \r und \n können wir in Visual Basic die Konstanten vbCr und VbLf für die Zeichen CR und LF verwenden. Zusätzlich gibt es die Konstante vbCrLf für den Windows-Zeilenumbruch beziehungsweise für beide Zeichen zusammen. In Delphi, FreePascal und Lazarus können wir die Zeichen direkt über ihre Zeichen-Codes #13 (CR) und #10 (LF) einfügen. Ähnlich verhält es sich in der Datenbanksprache SQL, in der wir in ähnlicher Weise CHAR(13) und CHAR(10) nutzen können, um die entsprechenden Zeichen zu erzeugen.

Variablen, Konstanten und Funktionen für den Systemzeilenumbruch

Neben dieser expliziten Definition von Zeilenumbrüchen stellen uns die meisten Programmiersprachen Variablen, Konstanten oder Funktionen zur Verfügung, mit denen sich plattformunabhängig der jeweilige Systemzeilenumbruch einfügen lässt:

Auf diese Weise können wir selber entscheiden, ob wir explizit einen bestimmten Zeilenumbruchtyp nutzen möchten (zum Beispiel weil unser Ziel ist, Dateien mit genau diesem Zeilenumbruchtyp zu speichern) oder ob unser Programm automatisch den passenden Systemzeilenumbruch einsetzen soll (zum Beispiel weil unser Programm auf verschiedenen Systemen eine jeweils passende Ausgabe erzeugen soll).

Netzwerkprotokolle

Auch in Netzwerkprotokollen spielt die Verwendung des richtigen Zeilenumbruchtyps eine große Rolle. Viele dieser Netzwerkprotokolle wie zum Beispiel HTTP, SMTP, FTP und IRC sind textbasiert und nutzen den Zeilenumbruchtyp CRLF für ihre zeilenweise übermittelten Requests.

Einige Programme halten sich strikt an diesen Standard und verweigern entsprechend die Verarbeitung von Requests, die einen anderen Zeilenumbruchtyp wie zum Beispiel LF verwenden (wie zum Beispiel qmail). Andere Programme sind toleranter in der Verarbeitung oder nutzen sogar fälschlicherweise stets den Systemzeilenumbruchtyp für ihre Requests, was zu Problemen in der Kommunikation mit Systemen führen kann, die den Standard strenger umsetzen. Einige dieser Probleme resultieren auch aus der Verwendung des C-typischen \n welches, wie wir im letzten Abschnitt gesehen haben, in Programmiersprachen wie C, C++, Perl und Haskell je nach Betriebssystem und Modus, entweder als das korrekte CRLF oder das inkorrekte LF aufgelöst werden kann.

Um diese Probleme zu vermeiden empfehlen einige Protokolle inzwischen auch andere Zeilenumbruchtypen als CRLF anzuerkennen. Mit der weiteren Verwendung von CRLF sind wir dennoch auf der richtigen Seite, da wir nicht wissen, welches möglicherweise veraltete Programm auf der Gegenseite verwendet wird.

Erkennung des Zeilenumbruchtyps einer Datei

Im Gegensatz zur Kodierung von Textdateien, deren "Encoding-ID" wir für bestimmte Unicode-Kodierungen als Erkennungszeichen in der Form einer sogenannten Byte Order Mark (BOM) an den Beginn einer Textdatei schreiben können, ist es bei der Erkennung des Zeilenumbruchtyps einer Datei nicht so einfach. Für den verwendeten Zeilenumbruchtyp einer Datei gibt es nichts vergleichbares was uns den Zeilenumbruchtyp auf ähnliche Weise signalisieren könnte wie die BOM. Wenn wir eine unbekannte Textdatei vor uns haben, bleiben uns daher lediglich einige Faustregeln, um den Zeilenumbruchtyp dieser Datei zu bestimmen.

Ein erstes Indiz liefert das Betriebssystem, auf dem die Textdatei erstellt wurde: Falls die Datei auf einem Windows-Rechner ihren Ursprung fand, ist der Windows-Zeilenumbruch CR LF wahrscheinlich. Wurde die Datei dagegen auf einem aktuellen Mac oder unter Linux erstellt, verwendet die Datei vermutlich einen Zeilenumbruch vom Unix-Typ LF. Jedoch kann es sich bei dieser Art von Einordnung allenfalls um eine Daumenregel handeln, da es zum Beispiel genug Texteditoren für Windows gibt, die zwar in ihrer Standardeinstellung den Windows-Zeilenumbruch voreingestellt haben mögen, mit denen es aber genauso auch möglich ist, Dateien unter Verwendung beliebiger anderer Zeilenumbruchtypen zu speichern. Darüber hinaus könnte es auch gänzlich unklar sein, von welchem System eine Datei überhaupt stammt.

Aus diesem Grund sollte man sich bei der Interpretation einer Textdatei unbekannten Ursprungs nicht auf derartige Vermutungen verlassen sondern versuchen, eine Entscheidung aufgrund der uns bekannten Bytes der Datei zu treffen. Dabei kann man zum Beispiel folgendermaßen vorgehen:

Zum Glück müssen wir die hier beschriebene Arbeit natürlich nur dann leisten, wenn wir selber ein Programm programmieren möchten, das mit allen Arten von Textdateien umgehen können soll. Ein Programm, dass dies bereits leisten kann, ist der TextKonverter: Standardmäßig arbeitet der TextKonverter mit der Einstellung "Zeilenumbruchtyp" > "Automatische Erkennung", was bedeutet, dass der TextKonverter die hier beschriebene Analyse Ihrer Dateien automatisch vornimmt und Sie davon gar nichts mitbekommen. Dennoch ist es mit dem TextKonverter natürlich auch möglich, diese Voreinstellung zu ändern und Dateien mit jeder beliebigen anderen Art von Zeilenumbruchtyp einzulesen oder zu speichern. Alle hier in diesem Artikel vorgestellten Zeilenumbruchtypen sind genauso verwendbar wie eine fixe Zeilenlänge oder auch einzelne oder mehrere beliebige benutzerdefinierte Zeichen oder Codepoints als Zeilenumbruch.

Probleme beim Austausch von Dateien

Aus den unterschiedlichen Kodierungen für den Zeilenumbruch erwachsen große Probleme beim Austausch von Dateien zwischen verschiedenen Systemen.

Die Probleme können dabei vielfältiger Natur sein:

Um derartige Dateien dennoch auch auf dem System Ihrer Wahl lesbar zu machen, gibt es zwei Möglichkeiten: Entweder verwenden wir ein Programm, dass auch exotische Typen von Zeilenumbrüchen versteht, oder wir tauschen das Zeichen für den Zeilenumbruch in diesen Dateien vor einer weiteren Ansicht oder Bearbeitung aus. Wie das funktioniert, schauen wir uns im nächsten Abschnitt an.

Änderung des Zeilenumbruchtyps von Dateien

Wenn Sie Textdateien von anderen Betriebsystemen oder sonstigen Quellen, die einen von Ihrem Betriebssystem abweichenden Zeilenumbruchtyp verwenden, auch auf Ihrem System nativ lesen möchten, können Sie die Zeilenumbrüche der betreffenden Dateien umschreiben beziehungsweise die alten Zeilenumbrüche gegen den von Ihnen präferierten Zeilenumbruchtyp austauschen. Solch eine Umschreibung kann darüber hinaus auch erforderlich sein, wenn Sie Ihre Textdateien mit einem Programm einlesen möchten, das nur eine bestimmte Art von Zeilenumbruchtyp versteht und selber keine Konvertierungen vornehmen kann.

Zeilenumbruchtyp mit dem TextEncoder ändern

Unabhängig davon, wofür Sie den Zeilenumbruchtyp von Dateien ändern möchten, können Sie diese Änderung komfortabel und sogar mit einer beliebigen Anzahl von Dateien gleichzeitig, mit der Software TextEncoder vornehmen. Folgen Sie dazu einfach den folgenden Schritten:

Der TextEncoder unterstützt sowohl für das Einlesen als auch für das Speichern der Textdateien alle in diesem Tutorial vorgestellten zeichenbasierten Zeilenumbruchtypen sowie Zeilenumbrüche nach einer festen Anzahl von Zeichen. Darüber hinaus können auch benutzerdefinierte Zeilenumbrüche über einzelne oder mehrere Zeichen oder Codepoints definiert und in der Anwendung verwendet werden.

Wenn Sie die Änderung des Zeilenumbruchs einzelner oder mehrerer Dateien (zum Beispiel aller Dateien aus einem spezifizierten Ordner) über ein Skript automatisieren möchten, können Sie dafür den TextEncoder in der Version TextEncoder Pro CL verwenden.

Zeilenumbruchtyp mit dem TextKonverter ändern

Auch mit dem Programm Text Konverter ist es möglich, die verwendeten Zeilenumbrüche von Textdateien zu ändern. Die Vorgehensweise ist die gleiche, wie sie soeben für den TextEncoder beschrieben wurde. Auch die Auswahl unterstützter Zeilenumbruchtypen ist zum TextEncoder identisch.

Jedoch befinden sich die Zeilenumbruch-Optionen beim TextKonverter nicht unter "Änderungen > Zeilenumbrüche" sondern unter "Aktionen > Dateien > Zeilenumbruchtyp". Darüber hinaus können Sie den TextKonverter auch für zahlreiche andere Bearbeitungen von Text-, CSV-, und XML-Dateien verwenden, während der TextEncoder nur dafür gedacht ist, die Kodierung sowie den Zeilenumbruchtyp von Textdateien zu ändern. Auch den Text Konverter gibt es als Batch Version, die sich über die Kommandozeile oder per Skript steuern und automatisieren lässt.

Dateien mit gemischten Zeilenumbrüchen

Im Abschnitt "Erkennung des Zeilenumbruchtyps einer Datei" hatten wir bereits den Fall angesprochen, dass es Textdateien geben kann, die mehrere Arten von Zeilenumbrüchen gleichzeitig enthalten können. Einer solche Datei kann dann keiner der möglichen Zeilenumbruchtypen eindeutig zugeordnet werden.

Entstehung von Dateien mit gemischten Zeilenumbrüchen

Entstehen können derartige Dateien mit gemischten Zeilenumbrüchen auf verschiedene Weise:

Möglich ist zum Beispiel, dass eine Datei von möglicherweise unterschiedlichen Personen auf verschiedenen Systemen bearbeitet wurde. Falls diese Personen beispielsweise einen Texteditor verwendet haben, der nur den eigenen System-Zeilenumbruchtyp verstehen und schreiben kann, ist folgendes schnell passiert: Person A erstellt eine Textdatei auf Linux. Die resultierende Datei enthält zu diesem Zeitpunkt ausschließlich den Unix-Zeilenumbruchtyp LF. Anschließend öffnet Person B die Datei unter Windows und beginnt einige Absätze hinzuzufügen. Diese neuen Absätze werden unter Verwendung des Windows-Zeilenumbruchs CR LF in die Datei hinein geschrieben, die alten LF-Zeilenumbrüche bleiben dagegen unangetastet. Schon trägt eine solche Datei ungewollt mehrere Arten von Zeilenumbrüchen in sich.

Dasselbe kann passieren, wenn mehrere Dateien unterschiedlicher Systeme aneinandergehängt werden, ohne vorher den Zeilenumbruchtyp der Dateien aufeinander abzustimmen.

Reparatur von Dateien mit gemischten Zeilenumbrüchen

Was können wir aber tun, wenn es schon zu spät ist? Wie können wir eine solche Datei mit gemischten Zeilenumbrüchen wieder reparieren? Zum Glück müssen wir uns darum nicht händisch kümmern, sondern können wieder zum TextEncoder greifen, der bereits im letzten Abschnitt vorgestellt wurde. Wie dies genau funktioniert, ist im Tutorial "Textdateien mit gemischten Zeilenumbrüchen reparieren" erklärt.

Und damit es beim nächsten Mal nicht wieder zu Dateien mit gemischten Zeilenumbrüchen kommt: Mehrere Text-Dateien unter Berücksichtigung ihrer verschiedenen Zeilenumbruchtypen aneinander zu hängen beherrscht das Programm TextKonverter. Und das natürlich ohne dass Sie sich explizit darum kümmern müssen.