J'ai entendu dire que vous devriez éviter de diriger les nouvelles lignes lors de l'utilisation printf
. Alors qu'au lieu de printf("\nHello World!")
vous devriez utiliserprintf("Hello World!\n")
Dans cet exemple particulier ci-dessus, cela n'a aucun sens, car le résultat serait différent, mais considérons ceci:
printf("Initializing");
init();
printf("\nProcessing");
process_data();
printf("\nExiting");
par rapport à:
printf("Initializing\n");
init();
printf("Processing\n");
process_data();
printf("Exiting");
Je ne vois aucun avantage avec les retours à la ligne, sauf que cela a l'air mieux. Y a-t-il une autre raison?
MODIFIER:
Je vais aborder les votes serrés ici et maintenant. Je ne pense pas que cela appartienne au débordement de pile, car cette question concerne principalement le design. Je dirais également que, même s’il s’agit peut-être d’opinions sur ce point, la réponse de Kilian Foth et celle de cmaster prouvent qu’une seule approche offre des avantages très objectifs.
init()
etprocess_data()
imprimer quelque chose eux-mêmes? À quoi penseriez-vous que le résultat ressemble s'ils le faisaient?\n
est un terminateur de ligne , pas un séparateur de ligne . Ceci est démontré par le fait que les fichiers texte, sous UNIX, finissent presque toujours par\n
.Réponses:
Un nombre suffisant d'E / S de terminal sont mises en mémoire tampon en ligne . Ainsi, en mettant fin à un message avec \ n, vous pouvez être certain qu'il sera affiché à temps. Avec un \ n en tête, le message peut ou non être affiché en même temps. Souvent, cela signifie que chaque étape affiche le message de progression de l' étape précédente , ce qui entraîne une confusion sans fin et une perte de temps lorsque vous essayez de comprendre le comportement d'un programme.
la source
fprintf(STDERR, …)
place, qui n'est généralement pas du tout tamponnée pour la sortie de diagnostic.Sur les systèmes POSIX (essentiellement n'importe quel système Linux, BSD, quel que soit le système basé sur le code source ouvert que vous puissiez trouver), une ligne est définie comme une chaîne de caractères qui se termine par une nouvelle ligne
\n
. Ceci est l'hypothèse de base , tous les outils standard de ligne de commande se fondent sur, y compris (mais sans s'y limiter)wc
,grep
,sed
,awk
etvim
. C’est aussi la raison pour laquelle un éditeur (commevim
) ajoute toujours un a\n
à la fin d’un fichier, et pourquoi les normes antérieures de C imposaient que les en-têtes se terminent par un\n
caractère.Btw: Avoir des
\n
lignes terminées rend le traitement du texte beaucoup plus facile: vous savez que vous avez une ligne complète lorsque vous avez ce terminateur. Et vous savez à coup sûr que vous devez examiner plus de caractères si vous n'avez pas encore rencontré ce terminateur.Bien sûr, cela se trouve du côté entrée des programmes, mais la sortie du programme est très souvent utilisée à nouveau comme entrée de programme. Votre sortie doit donc respecter la convention afin de permettre une entrée transparente dans d’autres programmes.
la source
En plus de ce que d'autres ont mentionné, j'ai l'impression qu'il existe une raison beaucoup plus simple: c'est la norme. Chaque fois que quelque chose est imprimé sur STDOUT, cela suppose presque toujours qu'il est déjà sur une nouvelle ligne et qu'il n'est donc pas nécessaire d'en démarrer une nouvelle. Cela suppose également que la prochaine ligne à écrire agira de la même manière, elle se termine donc utilement par une nouvelle ligne.
Si vous produisez des lignes de début de ligne entrelacées avec des lignes de fin de ligne standard, "cela ressemblera à ceci:
... ce qui n'est probablement pas ce que vous voulez.
Si vous utilisez uniquement des nouvelles lignes dans votre code et que vous l'exécutez dans un environnement de développement intégré, il se peut que cela se passe bien. Dès que vous l'exécutez dans un terminal ou introduisez le code d'une autre personne qui écrit dans STDOUT à côté de votre code, vous verrez une sortie indésirable comme ci-dessus.
la source
$PS1
, celle-ci serait irritante si vous suiviez des programmes classiques.Étant donné que les réponses fort élogieuses ont déjà fourni d'excellentes raisons techniques pour lesquelles les nouvelles lignes doivent être préférées, je l'aborderai sous un autre angle.
À mon avis, les éléments suivants rendent un programme plus lisible:
De ce qui précède, nous pouvons affirmer que les nouvelles lignes de fuite sont meilleures. Les nouvelles lignes formatent le "bruit" par rapport au message. Le message doit ressortir et doit donc apparaître en premier (la coloration syntaxique peut aussi aider).
la source
"ok\n"
c'est bien mieux que"\nok"
..."\pFoobar"
.L'utilisation des nouvelles lignes de fin simplifie les modifications ultérieures.
En tant qu'exemple (très trivial) basé sur le code de l'OP, supposons que vous deviez générer une sortie avant le message "Initializing" et que cette sortie provient d'une autre partie logique du code, située dans un fichier source différent.
Lorsque vous exécutez le premier test et que "Initializing" est ajouté à la fin d'une ligne d'une autre sortie, vous devez rechercher dans le code pour trouver où il a été imprimé, puis espérer que "Initializing" soit remplacé par "\ nInitializing". "ne bousille pas le format de quelque chose d'autre, dans des circonstances différentes.
Maintenant, réfléchissez à la manière dont vous allez gérer le fait que votre nouvelle sortie est en fait facultative. Par conséquent, le passage à "\ nInitializing" génère parfois une ligne blanche indésirable au début de la sortie ...
Définissez-vous un indicateur global ( horreur de choc? !!! ) indiquant s'il existe une sortie précédente et testez-le pour imprimer "Initializing" avec un "\ n" en tête, ou indiquez-vous le "\ n" en même temps votre sortie précédente et laissez les futurs lecteurs de code se demander pourquoi cette "initialisation" n'a pas un "\ n" majuscule, contrairement à tous les autres messages de sortie?
Si vous produisez régulièrement des retours à la ligne de fin, au moment où vous savez que vous avez atteint la fin de la ligne à terminer, vous évitez tous ces problèmes. Notez que cela peut nécessiter une instruction distincte ("\ n") à la fin d'une logique produisant une ligne pièce par pièce, mais le point est que vous exportez la nouvelle ligne à la première place dans le code, là où vous savez que vous devez faites-le, pas ailleurs.
la source
Correspondre étroitement à la spécification C.
La bibliothèque C définit une ligne comme se terminant par un caractère de nouvelle ligne
'\n'
.Le code qui écrit les données sous forme de lignes correspondra alors à ce concept de la bibliothèque.
Re: last line nécessite un caractère de fin de ligne . Je recommanderais de toujours écrire une finale
'\n'
en sortie et de tolérer son absence en entrée.Vérification orthographique
Mon correcteur orthographique se plaint. Peut-être que vous aussi.
la source
ispell.el
pour mieux faire face à cela. J'admets que c'était plus souvent\t
le problème, et il pourrait être évité simplement en divisant la chaîne en plusieurs jetons, mais ce n'était qu'un effet secondaire d'un travail plus général "ignorer", permettant de sauter de manière sélective des parties non textuelles de HTML. ou des corps en plusieurs parties MIME et des parties de code non commentées. Je voulais toujours l'étendre au changement de langue où il y a des métadonnées appropriées (par exemple<p lang="de_AT">
ouContent-Language: gd
), mais je n'ai jamais eu de Round Tuit. Et le responsable a carrément rejeté mon patch. :-(ispell.el
.Les nouvelles lignes majeures facilitent souvent l'écriture du code lorsqu'il existe des conditions, par exemple:
(Mais comme cela a été noté par ailleurs, vous devrez peut-être vider le tampon de sortie avant d'effectuer toute étape qui prend beaucoup de temps CPU.)
Par conséquent, un bon argument peut être présenté pour les deux façons de le faire, bien que personnellement je n'aime pas printf () et utiliserais une classe personnalisée pour construire la sortie.
la source
"\nProcessing"
.printf
. Et si vous vouliez conditionner la totalité de la ligne "Initializing"? Vous devez inclure la ligne "Processus" dans cette condition pour savoir si vous devez préfixer avec une nouvelle ligne ou non. S'il y a une autre impression à venir et que vous devez conditionner la ligne "Traitement", vous devez également inclure la prochaine impression dans cette condition pour savoir si vous devez préfixer par une nouvelle nouvelle ligne, et ainsi de suite pour chaque impression.if ((addr & 0x0F)==0) printf("\n%08X:", addr);
et d'ajouter sans condition une nouvelle ligne à la sortie à la fin, plutôt que d'utiliser code séparé pour l'en-tête de chaque ligne et la fin de ligne.Les nouvelles lignes ne fonctionnent pas bien avec les autres fonctions de la bibliothèque, notamment
puts()
etperror
dans la bibliothèque standard, mais également avec toute autre bibliothèque que vous êtes susceptible d'utiliser.Si vous souhaitez imprimer une ligne pré-écrite (une constante ou une déjà formatée - par exemple avec
sprintf()
),puts()
le choix est naturel (et efficace). Cependant, il n'y a aucun moyenputs()
de terminer la ligne précédente et d'écrire une ligne non terminée - elle écrit toujours le terminateur de ligne.la source