Quelle est la différence entre \ r et \ n?

245

Comment sont \ret \ndifférents? Je pense que cela a quelque chose à voir avec Unix vs Windows vs Mac, mais je ne sais pas exactement comment ils sont différents, et lesquels rechercher / faire correspondre dans les expressions rationnelles.

Sam Lee
la source
1
Cela nécessite une balise de langue. Différentes langues ont des interprétations différentes de '\n'.
Adrian McCarthy

Réponses:

383

Ce sont des personnages différents. \rest le retour chariot et le \nsaut de ligne.

Sur les "anciennes" imprimantes, \rrenvoyez la tête d'impression au début de la ligne et \navancez le papier d'une ligne. Les deux étaient donc nécessaires pour commencer l'impression sur la ligne suivante.

Évidemment, cela n'est plus pertinent maintenant, bien que, selon la console, vous puissiez toujours utiliser \rpour vous déplacer au début de la ligne et écraser le texte existant.

Plus important encore, Unix a tendance à utiliser \ncomme séparateur de ligne; Windows a tendance à utiliser \r\ncomme séparateur de ligne et Mac (jusqu'à OS 9) utilisé pour utiliser \rcomme séparateur de ligne. (Mac OS X est Unix-y, donc utilise à la \nplace; il peut y avoir des situations de compatibilité où \rest utilisé à la place cependant.)

Pour plus d'informations, consultez l' article de la nouvelle ligne Wikipedia .

EDIT: Ceci est sensible à la langue. En C # et Java, par exemple, signifie \n toujours Unicode U + 000A, qui est défini comme un saut de ligne. En C et C ++, l'eau est un peu plus boueuse, car la signification est spécifique à la plate-forme. Voir les commentaires pour plus de détails.

Jon Skeet
la source
22
+1 pour les personnes âgées. Sortie de terminal utilisée pour contrôler directement un terminal électronique glorifié (votre ATS avant ces affichages CRT de fantaisie). Par conséquent, nous obtenons de merveilleux artefacts de ceux dans les caractères de retour chariot et de nouvelle ligne (qui pourraient être nécessaires, comme l'a mentionné Jon Skeet) et des choses comme \ a "bell", \ b "backspace" (à ne pas confondre avec "delete "), et tous les autres caractères de contrôle nécessaires pour communiquer avec un tty.
erjiang
35
Un autre +1 pour les personnes âgées. Vous pouvez toujours appuyer sur Ctrl + G sur une invite de commande Windows, appuyez sur Entrée et le haut-parleur du PC émet un bip. Cela reste des temps anciens.
Dave Carlile
@Crappy Coding Guy vraiment? Sur Vista, il indique simplement que "" n'est pas reconnu comme une commande interne ou externe "
Ponkadoodle
2
@AdrianMcCarthy: Bien sûr, la question ne spécifie pas réellement C ou C ++ ici. En C #, par exemple, il \n est garanti qu'il s'agit d'une nouvelle ligne (section 2.4.4.4). Bien sûr, ce serait bien si l'OP avait spécifié la plate-forme ... En outre, je pense que ce niveau de détail serait plus déroutant qu'utile pour quelqu'un qui demande simplement la différence.
Jon Skeet
2
@AdrianMcCarthy: Mais en C # et Java au moins, il est à la ligne. C'est U + 000A, qui est nommé par Unicode comme "LINE FEED" (et NEW LINE). Je vais modifier pour mentionner le cas spécial de C et C ++, mais je crois vraiment que ce sont des cas spéciaux, et non l'inverse.
Jon Skeet
91

En C et C ++, \nest un concept, \rest un caractère et \r\nest (presque toujours) un bogue de portabilité.

Pensez à un vieux téléscripteur. La tête d'impression est positionnée sur une ligne et une colonne. Lorsque vous envoyez un caractère imprimable au téléscripteur, il imprime le caractère à la position actuelle et déplace la tête dans la colonne suivante. (C'est conceptuellement la même chose qu'une machine à écrire, sauf que les machines à écrire ont généralement déplacé le papier par rapport à la tête d'impression.)

Lorsque vous vouliez terminer la ligne actuelle et commencer sur la ligne suivante, vous deviez effectuer deux étapes distinctes:

  1. ramenez la tête d'impression au début de la ligne, puis
  2. déplacez-le vers la ligne suivante.

ASCII code ces actions en deux caractères de contrôle distincts:

  • \x0D(CR) ramène la tête d'impression au début de la ligne. (Unicode code cela comme U+000D CARRIAGE RETURN.)
  • \x0A(LF) déplace la tête d'impression vers le bas sur la ligne suivante. (Unicode code cela comme U+000A LINE FEED.)

À l'époque des télétypes et des premières imprimantes technologiques, les gens profitaient en fait du fait qu'il s'agissait de deux opérations distinctes. En envoyant un CR sans le suivre par un LF, vous pouvez imprimer sur la ligne que vous avez déjà imprimée. Cela a permis des effets comme les accents, les caractères gras et le soulignement. Certains systèmes ont été surimprimés plusieurs fois pour empêcher la visibilité des mots de passe sur papier. Sur les premiers terminaux série CRT, CR était l'un des moyens de contrôler la position du curseur afin de mettre à jour le texte déjà à l'écran.

Mais la plupart du temps, vous vouliez simplement passer à la ligne suivante. Plutôt que d'exiger la paire de caractères de contrôle, certains systèmes n'autorisaient que l'un ou l'autre. Par exemple:

  • Les variantes Unix (y compris les versions modernes de Mac) utilisent uniquement un caractère LF pour indiquer une nouvelle ligne.
  • Les anciens fichiers Macintosh (pré-OSX) utilisaient juste un caractère CR pour indiquer une nouvelle ligne.
  • VMS, CP / M, DOS, Windows et de nombreux protocoles réseau attendent toujours les deux: CR LF.
  • Anciens systèmes IBM qui utilisaient EBCDIC normalisé sur NL - un caractère qui n'existe même pas dans le jeu de caractères ASCII. En Unicode, NL est U+0085 NEXT LINE, mais la valeur EBCDIC réelle est 0x15.

Pourquoi différents systèmes ont-ils choisi différentes méthodes? Tout simplement parce qu'il n'y avait pas de norme universelle. Là où votre clavier dit probablement «Enter», les claviers plus anciens disaient «Return», ce qui était l'abréviation de Carriage Return. En fait, sur un terminal série, appuyer sur Retour envoie en fait le caractère CR. Si vous écriviez un éditeur de texte, il serait tentant de n'utiliser que ce caractère tel qu'il est venu du terminal. C'est peut-être la raison pour laquelle les anciens Mac utilisaient uniquement CR.

Maintenant que nous avons des normes , il existe plus de façons de représenter les sauts de ligne. Bien qu'extrêmement rare dans la nature, Unicode a de nouveaux personnages comme:

  • U+2028 LINE SEPARATOR
  • U+2029 PARAGRAPH SEPARATOR

Avant même l'arrivée d'Unicode, les programmeurs voulaient des moyens simples de représenter certains des codes de contrôle les plus utiles sans se soucier du jeu de caractères sous-jacent. C a plusieurs séquences d'échappement pour représenter les codes de contrôle:

  • \a (pour alerte) qui sonne la sonnerie du téléscripteur ou fait émettre un bip au terminal
  • \f (pour le formulaire) qui se déplace au début de la page suivante
  • \t (pour l'onglet) qui déplace la tête d'impression vers la position de l'onglet horizontale suivante

(Cette liste est intentionnellement incomplète.)

Ce mappage se produit au moment de la compilation - le compilateur voit \aet met la valeur magique utilisée pour sonner la cloche.

Notez que la plupart de ces mnémoniques ont des corrélations directes avec les codes de contrôle ASCII. Par exemple, \acorrespondrait à 0x07 BEL. Un compilateur peut être écrit pour un système qui utilise autre chose que ASCII pour le jeu de caractères hôte (par exemple, EBCDIC). La plupart des codes de contrôle qui avaient des mnémoniques spécifiques pouvaient être mappés à des codes de contrôle dans d'autres jeux de caractères.

Huzzah! Portabilité!

Enfin presque. En C, je pourrais écrire printf("\aHello, World!");qui sonne (ou émet un bip) et émet un message. Mais si je voulais ensuite imprimer quelque chose sur la ligne suivante, j'aurais encore besoin de savoir ce dont la plate-forme hôte a besoin pour passer à la ligne de sortie suivante. CR LF? CR? LF? NL? Autre chose? Voilà pour la portabilité.

C a deux modes pour les E / S: binaire et texte. En mode binaire, toutes les données envoyées sont transmises telles quelles. Mais en mode texte, il existe une traduction au moment de l'exécution qui convertit un caractère spécial en tout ce dont la plate-forme hôte a besoin pour une nouvelle ligne (et vice versa).

Génial, alors quel est le caractère spécial?

Eh bien, que la mise en œuvre de charge, aussi, mais il y a un moyen de mise en œuvre indépendante de le préciser: \n. Il est généralement appelé le "caractère de nouvelle ligne".

Il s'agit d'un point subtil mais important: \n est mappé au moment de la compilation sur une valeur de caractère définie par l'implémentation qui (en mode texte) est ensuite mappée à nouveau au moment de l' exécution sur le caractère réel (ou la séquence de caractères) requis par la plate-forme sous-jacente pour se déplacer à la ligne suivante.

\nest différent de tous les autres littéraux antislash car deux mappages sont impliqués. Ce mappage en deux étapes est \ntrès différent de pair \r, ce qui est simplement un mappage au moment de la compilation avec CR (ou le code de contrôle le plus similaire quel que soit le jeu de caractères sous-jacent).

Cela déclenche de nombreux programmeurs C et C ++. Si vous deviez en interroger 100, au moins 99 vous diront que cela \nsignifie un saut de ligne. Ce n'est pas tout à fait vrai. La plupart (peut-être toutes) les implémentations C et C ++ utilisent LF comme valeur intermédiaire magique pour \n, mais c'est un détail d'implémentation. Il est possible pour un compilateur d'utiliser une valeur différente. En fait, si le jeu de caractères hôte n'est pas un sur-ensemble d'ASCII (par exemple, s'il s'agit d'EBCDIC), alors ce \nne sera certainement pas LF.

Donc, en C et C ++:

  • \r est littéralement un retour chariot.
  • \nest une valeur magique qui est traduite (en mode texte) au moment de l' exécution vers / à partir de la sémantique de nouvelle ligne de la plate-forme hôte.
  • \r\nest presque toujours un bug de portabilité. En mode texte, cela est traduit en CR suivi de la séquence de nouvelle ligne de la plateforme - probablement pas ce qui est prévu. En mode binaire, cela est traduit en CR suivi d'une valeur magique qui pourrait ne pas être LF - peut-être pas ce qui est prévu.
  • \x0Aest le moyen le plus portable pour indiquer un LF ASCII, mais vous ne voulez le faire qu'en mode binaire. La plupart des implémentations en mode texte traiteront cela comme \n.
Adrian McCarthy
la source
Je suis tombé sur ce post tout en essayant de comprendre comment diviser l'entrée <textarea> en Python, et \r\nc'est en fait la seule façon de diviser correctement les lignes en éléments de liste séparés. Cela me fait me demander s'il s'agit d'un artefact HTML étrange ou s'il a à voir avec la façon dont Python ingère la chaîne de mon requestobjet.
Pat Jones
11
  • "\ r" => Retour
  • "\ n" => Retour à la ligne ou saut de ligne (sémantique)

  • Les systèmes basés sur Unix utilisent juste un "\ n" pour terminer une ligne de texte.

  • Dos utilise "\ r \ n" pour terminer une ligne de texte.
  • Certaines autres machines utilisaient juste un "\ r". (Commodore, Apple II, Mac OS avant OS X, etc.)
NoMoreZealots
la source
5

\r est utilisé pour pointer vers le début d'une ligne et peut remplacer le texte à partir de là, par exemple

main()
{
printf("\nab");
printf("\bsi");
printf("\rha");
}

Produit cette sortie:

hai

\n est pour la nouvelle ligne.

DAYA PHILIP
la source
4

En bref \ r a la valeur ASCII 13 (CR) et \ n a la valeur ASCII 10 (LF). Mac utilise CR comme délimiteur de ligne (au moins, il le faisait avant, je ne suis pas sûr pour les macs modernes), * nix utilise LF et Windows utilise les deux (CRLF).

Josip Medved
la source
1
Les systèmes Mac OS X utilisent LF par défaut (car il est basé sur BSD Unix).
dreamlax
3

En plus de la réponse de @Jon Skeet:

Traditionnellement, Windows utilise \ r \ n, Unix \ n et Mac \ r, mais les nouveaux Mac utilisent \ n car ils sont basés sur Unix.

Greg
la source
2

en C #, j'ai trouvé qu'ils utilisent \ r \ n dans une chaîne.

Wesley
la source
2

\ r est le retour chariot; \ n est New Line (Line Feed) ... dépend de l'OS quant à ce que chacun signifie. Lisez cet article pour en savoir plus sur la différence entre '\ n' et '\ r \ n' ... en C.

Nathan Loding
la source
1

\ r utilisé pour le retour chariot. (La valeur ASCII est 13) \ n utilisé pour la nouvelle ligne. (La valeur ASCII est 10)

Manjeet Kumar
la source