\r, \n oder \r\n ?
Till
- programmiertechnik
Moin!
Wenn ich eine Text Datei mit PHP erstelle was sollte ich dann an jedes Zeilenende setzen? \r, \n oder \r\n ?
rgds Till
Hi,
Wenn ich eine Text Datei mit PHP erstelle was sollte ich dann an jedes Zeilenende setzen? \r, \n oder \r\n ?
kurze Antwort: ja.
Längere Antwort: Nimm das, das dem/den auswertendem/n System/en am besten passt.
Cheatah
Hallo,
Wenn ich eine Text Datei mit PHP erstelle was sollte ich dann an jedes Zeilenende setzen? \r, \n oder \r\n ?
Wer oeffnet die Datei nachher?
Unter welchem Betriebssystem? Mit welchem Programm?
Als was (text/plain, text/html, ...)?
Mit \r\n solltest Du normalerweise auf der sicheren Seite sein.
Eventuell reicht auch \n.
http://www.tiptom.ch/homepage/faq.html?q=zeilenumbruch
Gruesse,
Thomas
Hallo Thomas,
Mit \r\n solltest Du normalerweise auf der sicheren Seite sein.
Nein. Mit diesen symbolischen Konstanten ist man *nicht* auf der
sicheren Seite. \n wird, abhängig von der Umgebung, bei der Ausgabe
mal nach \015\012 konvertiert, mal nach \012, mal nach \015.
Wenn man auf der *sicheren* Seite sein will, nennt man explizit,
was man haben will: \015\012 bzw. \012 bzw. \015.
Da fehlt mir ein Hinweis auf die Autokonvertierung von \n nach
\015\012 bzw. \015 bzw. \012. Eine unter Windows im ASCII-Modus
geschriebene Datei (z. B. fwrite($fd,"abc\nabc\n")) ergibt
"abc\015\012abc\015\012". Liest man die Datei unter Windows ein,
so ergibt das im Programm wieder "abc\nabc\n". Liest man dieselbe
Datei dagegen unter UNIX ein (vorrausgesetzt, sie wurde nicht
automatisch konvertiert, z. B. durch den ASCII-Modus von
FTP-Programmen), so gibt das "abc\015\nabc\015\n".
Grüße,
CK
Hallo,
http://www.tiptom.ch/homepage/faq.html?q=zeilenumbruch
Da fehlt mir ein Hinweis auf die Autokonvertierung von \n nach
\015\012 bzw. \015 bzw. \012.
Danke fuer die Erlaeuterungen.
Ich hatte bisher dem folgendem Manual-Abschnitt geglaubt:
http://www.php.net/manual/en/language.types.string.php#AEN3528
(Tabelle 6-1, siehe auch mein Posting [pref:t=71954&m=414348] von 15:02h)
Durch diesen Thread wurde mir klar, dass es bei
Datei-Operationen einige Problemchen gibt,
und ich werde meine Seite entsprechend aendern
und auch auf diesen Thread verlinken, sobald
er im Archiv ist.
Gruesse,
Thomas
Halihallo Till
Wenn ich eine Text Datei mit PHP erstelle was sollte ich dann an jedes Zeilenende setzen? \r, \n oder \r\n ?
Sollen? - Es gibt, wie du weisst, mehrere Möglichkeiten wie man das
Ende einer Zeile kodiert. Richtig sind alle. Falls du die Textdatei
für ein bestimmte Plattform schreiben möchtest, verwende die z.B.
okale Schreibweise "\015" (Mac), "\012" (Unix/*) oder "\015\012"
(Win).
Noch etwas: Sei vorsichtig mit "\n" oder "\r". Bei Perl z.B. ist
"\n" je nach Plattform einmal "\015\012", "\015" und "\012". Genauso
die von libc definierte Konstante "\n". PHP tanzt hier anscheinend
aus der Reihe und definiert \n generell als Oktalwert \015. Aber
hier ist wirklich vorsicht geboten, also verwendet man im
Zweifelsfall einfach die entsprechende Oktalschreibweise, dann hat
man absolute Sicherheit.
Viele Grüsse
Philipp
Hallo Philipp,
PHP tanzt hier anscheinend
aus der Reihe und definiert \n generell als Oktalwert \015.
Ja, aber: Wenn man eine Datei schreibt, und beim Öffnen *nicht* das Flag 'b' mit angegeben wurde (also fopen (..., 'w') und *nicht* fopen (..., 'wb')), dann wird \n (und auch \015!) automatisch zum Zeilenumbruch des jeweiligen Betriebsystems verwandelt (und beim Lesen natürlich genau umgekehrt).
Daher: Textdateien *nie* mit dem Flag 'b' öffnen und *immer* \n verwenden und PHP macht es dann für das Betriebsystem genau richtig.
Viele Grüße,
Christian
Halihallo Christian
Daher: Textdateien *nie* mit dem Flag 'b' öffnen und *immer* \n verwenden und PHP macht es dann für das Betriebsystem genau richtig.
Ach herje, mein Fehler. Ich hab's vorhin (doch) gerade ausprobiert.
Bei meinem Test lag es nicht am Flag 'b', sondern an dem Einlesen
von Perl, welches CRLF automatisch wieder in LF umgewandelt hat...
Das hat mir den Irrglauben aufgebunden, dass PHP \n automatisch mit
LF kodiert (obwohl ich eigentlich hätte merken müssen, dass es
eigentlich CR sein sollte, wenn man der Login von "\n\r" folgt)...
Schande über mich :-)
Fakt: Wenn man Textdateien für die aktuelle Platform schreiben
möchte: \n verwenden. Falls nicht: Die Zeichen "hart-kodiert" als
Oktal-/Hexadezimalzeichen schreiben um Fehler zu vermeiden für einen
guten Code[tm]... (hoffe, das ist jetzt richtig ;))
Viele Grüsse
Philipp
Halihallo Christian
Ach herje, mein Fehler. Ich hab's vorhin (doch) gerade ausprobiert.
Bei meinem Test lag es nicht am Flag 'b', sondern an dem Einlesen
von Perl, welches CRLF automatisch wieder in LF umgewandelt hat...
Das hat mir den Irrglauben aufgebunden, dass PHP \n automatisch mit
LF kodiert (obwohl ich eigentlich hätte merken müssen, dass es
eigentlich CR sein sollte, wenn man der Login von "\n\r" folgt)...
Stopp... Ich hab's doch in Perl mit binmode() eingelesen, Perl sollte
also jedes Byte genauso lassen, wie es ist.
test.php: (schreiben)
<?php
$fh = fopen("test.txt", "w");
fwrite($fh,"\n");
fclose($fh);
?>
test.pl: (einlesen und ASCII-Dump)
open( F, '<./test.txt' );
binmode(F);
my $t = '';
while ( read(F,$t,1) ) {
print ord($t)."\n";
}
close(F);
Nach Aufruf von test.php habe ich auf einem Windows-Rechner eine
Datei test.txt liegen, die genau ein Byte(!) aufweist (nach
Explorer). Der Perl-ASCII-Dump zeigt auch nur ein Zeichen, nämlich:
10 (\012). Obwohl die Datei a) zwei Bytes haben sollte und b) der
ASCII-Dump auf 10 13 lauten sollte.
Kann es sein, dass ich den Wald grad vor lauter Bäumen nicht mehr
sehe, oder habe ich einfach ein Unixisches PHP auf einem Windows-
Rechner?
Die Schlussfolgerung ist doch richtig, dass mein PHP anscheinend \n
mit dem ASCII-Wert 10 füttert, obwohl es eigentlich "\015\012" in die
Datei schreiben sollte (logisches Newline für Windows-Systeme).
Falls nicht, würde a) Perl das physikalische Newline (CRLF) in das
logische, interne LF umwandeln und Explorer(!) würde dasselbe machen.
Nun, M$ traue ich zwar einiges zu, aber eine Datei hat nunmal eine
eindeutig definierte Byte-Grösse, unabhängig von logischen Newlines
(gezählt werden die physikalisch vorhandenen).
? :-)
Viele Grüsse
Philipp
Hallo Philipp,
Kann es sein, dass ich den Wald grad vor lauter Bäumen nicht mehr
sehe, oder habe ich einfach ein Unixisches PHP auf einem Windows-
Rechner?
Aus http://php.net/fopen:
|Note: Different operating system families have different
|line-ending conventions. When you write a text file and want to
|insert a line break, you need to use the correct line-ending
|character(s) for your operating system. Unix based systems use
|\n as the line ending character, Windows based systems use \r\n
|as the line ending characters and Macintosh based systems use \r
|as the line ending character.
|If you use the wrong line ending characters when writing your
|files, you might find that other applications that open those
|files will "look funny".
|Windows offers a text-mode translation flag ('t') which will
|transparently translate \n to \r\n when working with the file. In
|contrast, you can also use 'b' to force binary mode, which will
|not translate your data. To use these flags, specify either 'b'
|or 't' as the last character of the mode parameter.
|The default translation mode depends on the SAPI and version of
|PHP that you are using, so you are encouraged to always specify
|the appropriate flag for portability reasons. You should use the
|'t' mode if you are working with plain-text files and you use \n
|to delimit your line endings in your script, but expect your files
|to be readable with applications such as notepad. You should use
|the 'b' in all other cases.
|If you do not specify the 'b' flag when working with binary files,
|you may experience strange problems with your data, including
|broken image files and strange problems with \r\n characters.
Und, das wichtigste:
|For portability, it is strongly recommended that you always use
|the 'b' flag when opening files with fopen().
|Again, for portability, it is also strongly recommended that you
|re-write code that uses or relies upon the 't' mode so that it
|uses the correct line endings and 'b' mode instead.
|As of PHP 4.3.2, the default mode is set to binary for all
|platforms that distinguish between binary and text mode. If you
|are having problems with your scripts after upgrading, try using
|the 't' flag as a workaround until you have made your script more
|portable as mentioned above.
Grüße,
CK
Halihallo Christian, Halihallo Thomas
[...]
Ich sollte etwas mehr die Doku lesen... Immerhin war meine
Feststellung korrekt, es besteht also noch Hoffung :-)
Danke an euch beide :-)
Viele Grüsse
Philipp
Hallo zusammen,
Ich erlaube mir, hier noch auf zwei Stellen
im PHP-Manual hinzuweisen:
http://www.php.net/manual/en/language.types.string.php#AEN3528
Table 6-1. Escaped characters
sequence meaning
\n linefeed (LF or 0x0A (10) in ASCII)
\r carriage return (CR or 0x0D (13) in ASCII)
Also gilt AFAICT grundsaetzlich:
\n = Dez. 10 = Oct. 12 = Hex. 0A
\r = Dez. 13 = Oct. 15 = Hex. 0D
Die Sache wird ausfuehrlich diskutiert auf der Seite zu fopen():
http://www.php.net/manual/en/function.fopen.php
"When you write a text file and want to insert a line
break, you need to use the correct line-ending character(s)
for your operating system.
[...]
Windows offers a text-mode translation flag ('t')
which will transparently translate \n to
\r\n when working with the file. In contrast, you
can also use 'b' to force binary mode, which will not
translate your data. To use these flags, specify either
'b' or 't' as the last character of the mode parameter."
Diese automatische Umwandlungs-Geschichte steht soweit
ich es verstehe also nur unter Windows zur Verfuegung,
und auch dann nur, wenn man es ausdruecklich festlegt.
Gruesse,
Thomas
Hallo Thomas,
Diese automatische Umwandlungs-Geschichte steht soweit
ich es verstehe also nur unter Windows zur Verfuegung,
und auch dann nur, wenn man es ausdruecklich festlegt.
Nein. Die automatische Umwandlungsgeschichte ist aktiv abhängig
von der PHP-Version (bzw. genauer von der SAPI-Version). Wie in
meinem Posting aus dem Manual zitiert:
|The default translation mode depends on the SAPI and version of
|PHP that you are using,
Grüße,
CK