it-swarm-eu.dev

Warum nachgestellte Zeilenumbrüche verwenden, anstatt mit printf zu führen?

Ich habe gehört, dass Sie führende Zeilenumbrüche vermeiden sollten, wenn Sie printf verwenden. Damit Sie anstelle von printf("\nHello World!")printf("Hello World!\n") verwenden sollten

In diesem speziellen Beispiel oben 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 Vorteil mit nachgestellten Zeilenumbrüchen sehen, außer dass es besser aussieht. Gibt es einen anderen Grund?

BEARBEITEN:

Ich werde hier und jetzt auf die engen Abstimmungen eingehen. Ich denke nicht, dass dies zum Stapelüberlauf gehört, da es bei dieser Frage hauptsächlich um Design geht. Ich würde auch sagen, dass Kilian Foths Antwort und cmasters Antwort beweisen, dass es tatsächlich sehr objektive Vorteile mit einem Ansatz gibt, obwohl es Meinungen zu dieser Angelegenheit sein mögen.

81
klutt

Eine angemessene Anzahl von Terminal-E/A ist zeilengepuffert. 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 Verwirrung und Zeitverschwendung führt, wenn Sie versuchen, das Verhalten eines Programms zu verstehen.

221
Kilian Foth

Auf POSIX-Systemen (im Grunde jedes Linux, BSD, egal welches Open-Source-basierte System Sie finden) wird eine Zeile als Zeichenfolge definiert, die durch eine neue Zeile \n Abgeschlossen wird. Dies ist die Grundannahme, auf der alle Standard-Befehlszeilentools aufbauen, einschließlich (aber nicht beschränkt auf) wc, grep, sed, awk und vim. Dies ist auch der Grund, warum einige Editoren (wie vim) immer ein \n Am Ende einer Datei hinzufügen und warum frühere Standards von C Header mit einem \n Zeichen.

Übrigens: Wenn \n Zeilen terminiert sind, wird die Textverarbeitung viel einfacher: Sie wissen sicher, dass Sie eine vollständige Zeile haben, wenn Sie diesen Terminator haben. Und Sie wissen mit Sicherheit, dass Sie sich mehr Zeichen ansehen müssen, wenn Sie diesem Terminator noch nicht begegnet sind.

Dies ist natürlich auf der Eingabeseite von Programmen, aber die Programmausgabe wird sehr oft wieder als Programmeingabe verwendet. Ihre Ausgabe sollte sich daher an die Konvention halten, um eine nahtlose Eingabe in andere Programme zu ermöglichen.

Zusätzlich zu dem, was andere erwähnt haben, gibt es meines Erachtens einen viel einfacheren Grund: Es ist der Standard. Wenn etwas in 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 Weise funktioniert, sodass sie hilfreich mit dem Beginn einer neuen Zeile endet.

Wenn Sie Zeilen mit führenden Zeilenumbrüchen ausgeben, die mit Standardzeilen mit nachfolgenden Zeilenumbrüchen verschachtelt sind, sieht dies folgendermaßen aus:

Trailing-newline-line
Trailing-newline-line

Leading-newline-line
Leading-newline-line
Leading-newline-lineTrailing-newline-line
Trailing-newline-line

Leading-newline-lineTrailing-newline-line
Trailing-newline-line
Trailing-newline-line

... was vermutlich nicht das ist, was du willst.

Wenn Sie in Ihrem Code nur führende Zeilenumbrüche verwenden und diese 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 einführen, der neben Ihrem Code in STDOUT schreibt, wird eine unerwünschte Ausgabe wie oben angezeigt.

31

Da die hoch bewerteten Antworten bereits hervorragende technische Gründe dafür angegeben haben, warum nachgestellte Zeilenumbrüche bevorzugt werden sollten, werde ich dies aus einem anderen Blickwinkel betrachten.

Meiner Meinung nach machen die folgenden Punkte ein Programm lesbarer:

  1. ein hohes Signal-Rausch-Verhältnis (auch bekannt als einfach, aber nicht einfacher)
  2. wichtige Ideen stehen an erster Stelle

Aus den obigen Punkten können wir argumentieren, dass nachgestellte Zeilenumbrüche besser sind. Zeilenumbrüche formatieren "Rauschen" im Vergleich zur Nachricht. Die Nachricht sollte hervorstechen und daher an erster Stelle stehen (Syntaxhervorhebung kann ebenfalls hilfreich sein).

17
Alex Vong

Die Verwendung von nachgestellten Zeilenumbrüchen vereinfacht spätere Änderungen.

Angenommen, Sie müssen als (sehr triviales) Beispiel, das auf dem OP-Code basiert, eine Ausgabe vor der Nachricht "Initializing" erstellen, und diese Ausgabe stammt von ein anderer logischer Teil des Codes in einer anderen Quelldatei.

Wenn Sie den ersten Test ausführen und feststellen, dass "Initialisierung" jetzt an das Ende einer Zeile einer anderen Ausgabe angehängt ist, müssen Sie den Code durchsuchen, um herauszufinden, wo er gedruckt wurde, und dann hoffen, "Initialisierung" in "\ nInitialisierung" zu ändern "vermasselt nicht das Format von etwas anderem, unter verschiedenen Umständen.

Überlegen Sie nun, wie Sie mit der Tatsache umgehen sollen, dass Ihre neue Ausgabe tatsächlich optional ist, sodass Ihre Änderung in "\ nInitializing" manchmal zu Beginn der Ausgabe eine unerwünschte Leerzeile erzeugt ...

Setzen Sie ein globales ( Schockhorror ?? !!! ) Flag, das angibt, ob eine vorherige Ausgabe vorhanden war, und testen Sie es, um "Initializing" mit einem zu drucken optionales führendes "\ n", oder geben Sie das "\ n" zusammen mit Ihrer früheren Ausgabe aus und lassen zukünftige Codeleser sich fragen, warum diese "Initialisierung" dies nicht tut ein führendes "\ n" haben wie alle anderen Ausgabenachrichten?

Wenn Sie konsistent nachgestellte Zeilenumbrüche ausgeben und an dem Punkt, an dem Sie wissen, dass Sie das Ende der Zeile erreicht haben, die beendet werden muss, alle diese Probleme umgehen. Beachten Sie, dass möglicherweise eine separate Puts-Anweisung ("\ n") am Ende einer Logik erforderlich ist, die eine Zeile Stück für Stück ausgibt. Der Punkt ist jedoch, dass Sie die neue Zeile an der frühesten Stelle ausgeben in dem Code, in dem Sie wissen, dass Sie es tun müssen, nicht woanders.

16
alephzero

Warum nachgestellte Zeilenumbrüche verwenden, anstatt mit printf zu führen?

Entspricht genau der C-Spezifikation

Die C-Bibliothek definiert eine Zeile als Ende mit einem Zeilenumbruchzeichen '\n'.

Ein Textstrom ist eine geordnete Folge von Zeichen, die aus Zeilen bestehen, wobei jede Zeile aus null oder mehr Zeichen plus einem abschließenden Zeichen in einer neuen Zeile besteht. Ob für die letzte Zeile ein abschließendes Zeichen für eine neue Zeile erforderlich ist, ist implementierungsdefiniert. C11 §7.21.2 2

Code, der Daten als Zeilen schreibt, stimmt dann mit diesem Konzept der Bibliothek überein.

printf("Initializing"); // Write part of a line
printf("\nProcessing"); // Finish prior line & write part of a line
printf("\nExiting");    // Finish prior line & write an implementation-defined last line

printf("Initializing\n");//Write a line 
printf("Processing\n");  //Write a line
printf("Exiting");       //Write an implementation-defined last line

Betreff: Die letzte Zeile erfordert ein abschließendes Zeichen für eine neue Zeile . Ich würde empfehlen, bei der Ausgabe immer ein endgültiges '\n' Zu schreiben und dessen Abwesenheit bei der Eingabe zu tolerieren.


Rechtschreibprüfung

Meine Rechtschreibprüfung beschwert sich. Vielleicht tust du es auch.

  v---------v Not a valid Word
"\nProcessing"

 v--------v OK
"Processing\n");

Führende Zeilenumbrüche erleichtern häufig das Schreiben des Codes, wenn beispielsweise Bedingungen vorliegen.

printf("Initializing");
if (jobName != null)
    printf(": %s", jobName);
init();
printf("\nProcessing");

(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 ein guter Fall für beide Arten gemacht werden, aber persönlich mag ich printf () nicht und würde eine benutzerdefinierte Klasse verwenden, um die Ausgabe aufzubauen.

4
Ian

Führende Zeilenumbrüche funktionieren nicht gut mit anderen Bibliotheksfunktionen, insbesondere puts() und perror in der Standardbibliothek, aber auch mit jeder anderen Bibliothek, die Sie wahrscheinlich verwenden.

Wenn Sie eine vorab geschriebene Zeile drucken möchten (entweder eine Konstante oder eine bereits formatierte - z. B. mit sprintf()), ist puts() die natürliche (und effiziente) Wahl. Es gibt jedoch keine Möglichkeit für puts(), die vorherige Zeile zu beenden und eine nicht abgeschlossene Zeile zu schreiben - es wird immer der Zeilenabschluss geschrieben.

1
Toby Speight