2009-12-15 16 views
11

Nachdenken über UNIX, Windows und Mac und einen Ausgangsstrom (sowohl binär und Text),Was bedeutet std :: endl genau auf jeder Plattform?

Was std::endl darstellt, das heißt <CR><LF>, <LF> oder <CR>? Oder ist es immer gleich, egal welche Plattform/Compiler?

Der Grund warum ich frage ist, dass ich einen TCP-Client schreibe, der ein Protokoll spricht, das erwartet, dass jeder Befehl in <CR><LF> endet. Also frage ich mich, ob ich std::endl oder "\r\n" in meinen Streams verwenden soll.

EDIT: Ok, so löscht man den Puffer und anderen nicht. Ich verstehe das. Aber wenn ich Text in eine Datei austausche, ist '\n' gleich <LF> oder konvertiert es zu <CR><LF> auf Windows und <LF> auf Unix oder nicht? Ich sehe noch keine klare Antwort.

Antwort

11

der Code.

stream << std::endl; 

// Is equivalent to: 

stream << "\n" << std::flush; 

Die Frage ist also, was auch "\ n" zugeordnet ist.
Auf normalen Streams passiert nichts.Aber für Dateiströme (im Textmodus) wird das "\ n" auf die Zeilenende-Sequenz der Plattform übertragen. Hinweis: Beim Lesen wird die Zeilenende-Sequenz der Plattform in ein '\ n' konvertiert, wenn sie im Textmodus aus einer Datei liest.

Wenn Sie also einen normalen Stream verwenden, passiert nichts. Wenn Sie einen Datei-Stream verwenden, stellen Sie nur sicher, dass er im Binärmodus geöffnet ist, so dass keine Konvertierung angewendet wird:

2

Zitiert aus der akzeptierten Antwort auf related question:

Die unterschiedlichen Zeilenende-Zeichen im Textmodus geöffnet keine Rolle spielt, ist die Datei unter der Annahme, das ist, was Sie, wenn Sie für binäre fragen bekommen. Das kompilierte Programm schreibt das Richtige für das kompilierte System aus.

Der einzige Unterschied ist, dass std :: endl den Ausgabepuffer löscht, und '\ n' nicht. Wenn der Puffer nicht häufig gelöscht werden soll, verwenden Sie '\ n'. Wenn Sie das tun (zum Beispiel, wenn Sie wollen, dass alle Ausgabe zu erhalten, und das Programm ist instabil), verwenden Sie std :: endl

In Ihrem Fall, da Sie speziell <CR><LF> wollen, sollten Sie explizit \r\n verwenden, Rufen Sie dann std::flush() auf, wenn Sie den Ausgabepuffer immer noch leeren möchten.

+0

Rep. Für die Annahme der akzeptierten Antwort auf eine Dup Frage? Wo sind die fünfzehn oder so SO Nazis, wenn du sie brauchst? –

+0

@Rob Wells: Ich habe darüber nachgedacht, aber entschieden, dass es nicht anders ist, als eine andere Referenzquelle in meiner Antwort zu zitieren, was natürlich vollkommen akzeptabel ist. Die Upvotes dienen der Bereitstellung von Informationen, die für die vorliegende Frage relevant sind. –

+1

Rob, ich sehe keine Duplikate. Diese Frage und die zitierte Frage sind sicherlich ähnlich, aber sie sind keine genauen Duplikate. Darüber hinaus fügt James eine Zusammenfassung nach dem Zitat hinzu, um diese Frage speziell anzusprechen. Außerdem bekommen die Leute den Ruf, dass sie die Antworten, die sie woanders finden, immer wieder zitieren. Sollte es einen Unterschied machen, wenn "anderswo" dieselbe Website ist? Bist du eifersüchtig oder was? –

0

Sieht so aus, als wäre Ihre Frage misslungen. Jeder Befehl endet in []? Für ein Over-the-Wire-Protokoll würde ich vorschlagen, ein Trennzeichen zu verwenden, das nicht nach Plattform variiert. std :: endl könnte abhängig von der Plattform in '\ r \ n' oder '\ n \ r' aufgelöst werden.

+0

true. Vielleicht ist es sinnvoller zu fragen, wann man '\ r \ n' vs std :: endl verwenden soll? – Matt

4

Verwenden Sie stream << "\r\n" (und öffnen Sie den Stream im Binärmodus). stream << std::endl; entspricht stream << "\n" << flush;. Das "\ n" könnte in ein "\ r \ n" konvertiert werden, wenn der Code unter Windows ausgeführt wird, aber Sie können nicht darauf zählen - mindestens ein Windows-Compiler konvertiert es in "\ n \ r". Auf einem Mac wird es wahrscheinlich in "\ r" konvertiert und auf Unix/Linux und den meisten ähnlichen Systemen wird es nur als "\ n" belassen.

+0

Wenn '\ n' in' \ r \ n' konvertiert wird, dann würde '\ r. \ n' in '\ r \ r \ n' übersetzt werden?" \ r \ n \ "wäre dann nicht genug. Er müsste auch sicherstellen, dass der Stream im Binärmodus ist, um die Übersetzung zu unterdrücken. –

+0

"\ n" wird in das entsprechende Format auf einer bestimmten Plattform konvertiert, wenn der Stream im Textmodus geöffnet wird (dh wenn Sie das Flag "ios_base :: binary" nicht verwendet haben) und Sie _können_ darauf zählen. –

+0

Of natürlich, wenn man '\ r \ n' im Stream braucht, unabhängig von der Plattform, dann muss' "\ r \ n" 'verwendet werden, und außerdem muss der Stream mit' ios_base :: binary' geöffnet werden. –

7

Die C++ Standard sagt, dass es:

fordert os.put (os.widen ('\ n')), dann os.flush()

Was die ‚\ n‘umgewandelt wird, wenn es überhaupt umgewandelt wird, ist bis auf die Stream-Typ wird verwendet, auf, sowie mögliche Betriebsart der Strom in geöffnet werden