Ich habe gehört, dass Sie bei der Verwendung Zeilenumbrüche vermeiden sollten printf
. Damit printf("\nHello World!")
solltest du stattdessen verwendenprintf("Hello World!\n")
In diesem speziellen obigen Beispiel ist dies nicht sinnvoll, da die Ausgabe unterschiedlich wäre. Beachten Sie jedoch Folgendes:
printf("Initializing");
init();
printf("\nProcessing");
process_data();
printf("\nExiting");
verglichen mit:
printf("Initializing\n");
init();
printf("Processing\n");
process_data();
printf("Exiting");
Ich kann keinen Nutzen mit nachgestellten Zeilenumbrüchen sehen, außer dass es besser aussieht. Gibt es noch einen anderen Grund?
BEARBEITEN:
Ich werde hier und jetzt auf die engen Abstimmungen eingehen. Ich glaube nicht, dass dies zum Stapelüberlauf gehört, da es sich bei dieser Frage hauptsächlich um Design handelt. Ich würde auch sagen , dass , obwohl es Meinungen in dieser Angelegenheit sein kann, Kilian Foth Antwort und cMaster Antwort beweist , dass es in der Tat sehr objektive Vorteile mit einem Ansatz.
init()
undprocess_data()
drucken? Wie würde das Ergebnis dann aussehen?\n
ist eine Linie Terminator , keine Linie Separator . Dies wird durch die Tatsache belegt, dass Textdateien unter UNIX fast immer auf enden\n
.Antworten:
Eine angemessene Anzahl von Terminal-E / A -Vorgängen wird zeilenweise gepuffert. Wenn Sie also eine Nachricht mit \ n beenden, können Sie sicher sein, dass sie rechtzeitig angezeigt wird. Mit einem führenden \ n kann die Nachricht sofort angezeigt werden oder nicht. Dies bedeutet häufig, dass in jedem Schritt die Fortschrittsmeldung des vorherigen Schritts angezeigt wird , was zu erheblicher Verwirrung und Zeitverschwendung führt, wenn Sie versuchen, das Verhalten eines Programms zu verstehen.
quelle
fprintf(STDERR, …)
stattdessen verwenden sollten, was für die Diagnoseausgabe im Allgemeinen überhaupt nicht gepuffert wird.Auf POSIX-Systemen (im Grunde jedes Linux- oder BSD-System, unabhängig davon, welches Open-Source-System Sie finden) wird eine Zeile als Zeichenfolge definiert, die durch einen Zeilenumbruch abgeschlossen wird
\n
. Dies ist die grundlegende Annahme , alle Standard - Kommandozeilen - Tools bauen auf, einschließlich (aber nicht beschränkt auf)wc
,grep
,sed
,awk
, undvim
. Dies ist auch der Grund, warum einige Editoren (wievim
) immer ein\n
am Ende einer Datei einfügen und frühere Standards von C forderten, dass Header mit einem\n
Zeichen enden .Übrigens: Durch das
\n
Beenden von Zeilen wird die Verarbeitung von Text erheblich vereinfacht: Sie wissen mit Sicherheit, dass Sie mit diesem Abschlusszeichen eine vollständige Zeile haben. Und Sie wissen sicher, dass Sie sich mehr Charaktere ansehen müssen, wenn Sie diesen Terminator noch nicht kennen.Natürlich ist dies auf der Eingabeseite von Programmen, aber die Programmausgabe wird sehr oft wieder als Programmeingabe verwendet. Ihre Ausgabe sollte sich also an die Konvention halten, um eine nahtlose Eingabe in andere Programme zu ermöglichen.
quelle
Zusätzlich zu dem, was andere erwähnt haben, gibt es meines Erachtens einen viel einfacheren Grund: Es ist der Standard. Wenn etwas auf STDOUT gedruckt wird, wird fast immer davon ausgegangen, dass es sich bereits in einer neuen Zeile befindet und daher keine neue Zeile beginnen muss. Es wird auch davon ausgegangen, dass die nächste zu schreibende Zeile auf die gleiche Art und Weise verhält, sodass sie hilfreich endet, wenn eine neue Zeile beginnt.
Wenn Sie Zeilen mit Zeilenvorschub und Zeilen mit Zeilenvorschub "verschachtelt" mit Standardzeilen mit Zeilenvorschub ausgeben, sieht dies am Ende so aus:
... was vermutlich nicht das ist, was du willst.
Wenn Sie in Ihrem Code nur führende Zeilenumbrüche verwenden und ihn nur in einer IDE ausführen, ist dies möglicherweise in Ordnung. Sobald Sie es in einem Terminal ausführen oder den Code anderer Personen eingeben, der neben Ihrem Code in STDOUT geschrieben wird, werden unerwünschte Ausgaben wie oben angezeigt.
quelle
$PS1
, der bei herkömmlichen Programmen ärgerlich wäre.Da die hochgestimmten Antworten bereits hervorragende technische Gründe dafür geliefert haben, warum Zeilenumbrüche vorzuziehen sind, werde ich sie aus einem anderen Blickwinkel betrachten.
Meiner Meinung nach verbessern die folgenden Punkte die Lesbarkeit eines Programms:
Aus den obigen Punkten können wir argumentieren, dass nachgestellte Zeilen besser sind. Zeilenumbrüche formatieren "Noise" im Vergleich zur Nachricht, die Nachricht sollte hervorstechen und daher an erster Stelle stehen (Syntax-Hervorhebung kann ebenfalls hilfreich sein).
quelle
"ok\n"
ist viel besser als"\nok"
..."\pFoobar"
.Die Verwendung von nachgestellten Zeilenumbrüchen vereinfacht spätere Änderungen.
Angenommen, Sie müssen als (sehr einfaches) Beispiel, das auf dem OP-Code basiert, vor der Meldung "Initializing" eine Ausgabe erstellen, die von einem anderen logischen Teil des Codes in einer anderen Quelldatei stammt.
Wenn Sie den ersten Test ausführen und feststellen, dass "Initialisierung" jetzt am Ende einer Zeile einer anderen Ausgabe angehängt ist, müssen Sie den Code durchsuchen, um herauszufinden, wo er gedruckt wurde, und dann hoffen, dass "Initialisierung" in "\ nInitialisierung" geändert wird "vermasselt nicht das Format von etwas anderem unter anderen Umständen.
Überlegen Sie nun, wie Sie mit der Tatsache umgehen sollen, dass Ihre neue Ausgabe tatsächlich optional ist, sodass Ihre Änderung an "\ nInitialisieren" manchmal zu einer unerwünschten Leerzeile am Anfang der Ausgabe führt ...
Setzen Sie ein globales Flag ( Schock Horror ?? !!! ), das angibt, ob zuvor eine Ausgabe erfolgt ist, und testen Sie es, um "Initializing" mit einem optionalen führenden "\ n" zu drucken, oder geben Sie das "\ n" zusammen mit aus Ihre frühere Ausgabe und lassen zukünftige Codeleser sich fragen, warum diese "Initialisierung" kein führendes "\ n" hat wie alle anderen Ausgabenachrichten?
Wenn Sie konsequent nachgestellte Zeilenumbrüche ausgeben und wissen, dass Sie das Ende der zu terminierenden Zeile erreicht haben, umgehen Sie alle diese Probleme. Beachten Sie, dass am Ende einer Logik, die eine Zeile Stück für Stück ausgibt, möglicherweise eine separate Anweisung puts ("\ n") erforderlich ist. Der Punkt ist jedoch, dass Sie die neue Zeile an der frühesten Stelle im Code ausgeben, an der Sie dies wissen Mach es, nicht woanders.
quelle
Übereinstimmung mit C-Spezifikation
Die C - Bibliothek definiert eine Linie als endend mit einer neuen Zeilenwechselzeichen
'\n'
.Code, der Daten als Zeilen schreibt , entspricht dann dem Konzept der Bibliothek.
Betreff: Letzte Zeile erfordert ein abschließendes Zeichen für eine neue Zeile . Ich würde empfehlen, immer ein Finale
'\n'
für die Ausgabe zu schreiben und dessen Fehlen bei der Eingabe zu tolerieren.Rechtschreibprüfung
Meine Rechtschreibprüfung beschwert sich. Vielleicht auch.
quelle
ispell.el
, um damit besser fertig zu werden. Ich gebe zu, es war häufiger\t
das Problem, und es konnte einfach durch Aufteilen der Zeichenfolge in mehrere Token vermieden werden, aber es war nur ein Nebeneffekt der allgemeineren "Ignorier" -Arbeit, Nicht-Text-Teile von HTML selektiv zu überspringen oder MIME-Body mit mehreren Teilen und kommentarlose Codeteile. Ich wollte es immer auf das Wechseln der Sprache ausweiten, wenn geeignete Metadaten (z. B.<p lang="de_AT">
oderContent-Language: gd
) vorhanden sind, habe aber nie einen Round Tuit erhalten. Und der Betreuer lehnte meinen Patch sofort ab. :-(ispell.el
.Führende Zeilenumbrüche erleichtern häufig das Schreiben des Codes, wenn Bedingungen vorliegen, z. B.
(Wie bereits an anderer Stelle erwähnt, müssen Sie möglicherweise den Ausgabepuffer leeren, bevor Sie Schritte ausführen, die viel CPU-Zeit in Anspruch nehmen.)
Daher kann für beide Methoden ein guter Fall gemacht werden, allerdings mag ich printf () persönlich nicht und würde eine benutzerdefinierte Klasse verwenden, um die Ausgabe aufzubauen.
quelle
"\nProcessing"
.printf
. Was wäre, wenn Sie die gesamte Zeile "Initializing" konditionieren wollten? Sie müssten die Zeile "Procesing" in diese Bedingung aufnehmen, um zu wissen, ob Sie eine neue Zeile voranstellen sollten oder nicht. Wenn ein weiterer Druck voraus ist und Sie die Zeile "Verarbeitung" konditionieren müssen, müssen Sie auch den nächsten Druck in diesen Zustand einbeziehen, um zu wissen, ob Sie für jeden Druck einen anderen Zeilenumbruch vorschreiben sollten, und so weiter.if ((addr & 0x0F)==0) printf("\n%08X:", addr);
eine neue Zeile am Ende der Ausgabe zu sagen und sie bedingungslos hinzuzufügen, als sie zu verwenden Separater Code für die Kopfzeile jeder Zeile und die nachfolgende Zeile.Führende Zeilenumbrüche funktionieren nicht gut mit anderen Bibliotheksfunktionen, insbesondere nicht
puts()
undperror
in der Standard - Bibliothek, aber auch jede andere Bibliothek , die Sie wahrscheinlich zu verwenden sind.Wenn Sie eine vorab geschriebene Zeile drucken möchten (entweder eine Konstante oder eine bereits formatierte - z. B. mit
sprintf()
),puts()
ist dies die natürliche (und effiziente) Wahl. Es gibt jedoch keine Möglichkeitputs()
, die vorherige Zeile zu beenden und eine nicht abgeschlossene Zeile zu schreiben - es wird immer der Zeilenabschluss geschrieben.quelle