web-dev-qa-db-fra.com

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

En quoi \r et \n sont-ils différents? Je pense que cela a quelque chose à voir avec Unix contre Windows contre Mac, mais je ne sais pas exactement en quoi ils sont différents, ni lesquels rechercher/faire correspondre dans des expressions rationnelles.

229
Sam Lee

Ce sont des personnages différents. \r est un retour chariot et \n est un saut de ligne.

Sur les "anciennes" imprimantes, \r a renvoyé la tête d'impression au début de la ligne et \n a avancé le papier d'une ligne. Les deux étaient donc nécessaires pour commencer à imprimer sur la ligne suivante.

Évidemment, cela a peu d'importance maintenant, même si, en fonction de la console, vous pourrez toujours utiliser \r pour vous déplacer au début de la ligne et écraser le texte existant.

Plus important encore, Unix a tendance à utiliser \n comme séparateur de ligne; Windows a tendance à utiliser \r\n comme séparateur de ligne et les Mac (jusqu’à OS 9) utilisaient pour utiliser \r comme ligne. séparateur. (Mac OS X étant Unix-y, il utilise donc \n à la place; il peut y avoir des situations de compatibilité dans lesquelles \r est utilisé à la place.)

Pour plus d'informations, voir le article de nouvelle ligne de Wikipedia .

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

362
Jon Skeet

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

Pensez à un ancien téléscripteur. La tête d'impression est positionnée sur une ligne et dans une colonne. Lorsque vous envoyez un caractère imprimable au télétype, il imprime le caractère à la position actuelle et déplace la tête vers la colonne suivante. (Ceci est conceptuellement identique à une machine à écrire, sauf que les machines à écrire déplacent généralement le papier par rapport à la tête d'impression.)

Lorsque vous souhaitez terminer la ligne en cours et commencer à la ligne suivante, vous devez effectuer deux étapes distinctes:

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

ASCII code ces actions sous la forme de deux caractères de contrôle distincts:

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

À l'époque des télétypes et des imprimantes à technologie ancienne, les gens profitaient 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 permettait des effets comme les accents, les caractères gras et le soulignement. Certains systèmes ont été surimprimés plusieurs fois pour éviter que les mots de passe ne soient visibles sur papier. Sur les premiers terminaux CRT série, CR était l’un des moyens de contrôler la position du curseur afin de mettre à jour le texte déjà affiché à 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 juste un caractère LF pour indiquer une nouvelle ligne.
  • Les anciens fichiers Macintosh (antérieurs à OSX) utilisaient simplement 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 utilisant EBCDIC normalisé sur NL - caractère qui n'existe même pas dans le jeu de caractères ASCII. En Unicode, NL correspond à U+0085 NEXT LINE, mais la valeur réelle EBCDIC 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 "Entrée", les anciens claviers disaient "Retour", qui était l'abréviation de Carriage Return. En fait, sur un terminal série, appuyer sur Retour envoie le caractère CR. Si vous écriviez un éditeur de texte, il serait tentant d’utiliser ce caractère tel qu’il venait du terminal. C'est peut-être pour cette raison que les anciens Mac utilisaient uniquement CR.

Maintenant que nous avons standards , il y a plus de façons de représenter les sauts de ligne. Bien qu'extrêmement rare dans la nature, Unicode a de nouveaux caractères tels que:

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

Même avant l'arrivée de l'Unicode, les programmeurs voulaient des moyens simples pour 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 ou sonne le bip du terminal
  • \f (pour le saut de formulaire) qui se déplace au début de la page suivante
  • \t (pour la tabulation) qui déplace la tête d'impression à la position de tabulation horizontale suivante

(Cette liste est intentionnellement incomplète.)

Ce mappage a lieu à au moment de la compilation - le compilateur voit \a et met la valeur magique utilisée pour faire 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, \a mapperait sur 0x07 BEL. Un compilateur peut être écrit pour un système utilisant autre chose que ASCII pour le jeu de caractères de l'hôte (par exemple, EBCDIC). La plupart des codes de contrôle ayant des mnémoniques spécifiques peuvent être mappés aux codes de contrôle d'autres jeux de caractères.

Huzzah! Portabilité!

Enfin presque. En C, je pourrais écrire printf("\aHello, World!"); qui sonne la cloche et émet un message. Mais si je voulais ensuite imprimer quelque chose sur la ligne suivante, il me faudrait tout de même 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, 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 inversement).

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

Cela dépend également de l'implémentation, mais il existe un moyen de le spécifier indépendamment de l'implémentation: \n. On l'appelle généralement le "caractère de nouvelle ligne".

Ceci est un point subtil mais important: \n est mappé à le temps de compilation en un 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 passer à la ligne suivante.

\n est différent de tous les autres littéraux de barre oblique inversée, car deux mappages sont impliqués. Ce mappage en deux étapes rend \n sensiblement différent de même \r, qui est simplement un mappage de compilation vers CR (ou le code de contrôle le plus similaire, quel que soit le jeu de caractères sous-jacent).

Cela provoque de nombreux programmeurs C et C++. Si vous devez en interroger 100, au moins 99 vous diront que \n signifie 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 il s'agit d'un détail d'implémentation. Il est possible qu'un compilateur utilise une valeur différente. En fait, si le jeu de caractères de l'hôte n'est pas un sur-ensemble de ASCII (par exemple, si c'est EBCDIC), alors \n ne sera presque certainement pas LF.

Donc, en C et C++:

  • \r est littéralement un retour à la ligne.
  • \n est une valeur magique qui est traduite (en mode texte) à au moment de l'exécution vers/à partir de la sémantique newline de la plateforme hôte.
  • \r\n est presque toujours un bug de portabilité. En mode texte, cela est traduit en CR, suivi de la séquence de nouvelle ligne de la plate-forme - probablement pas ce qui était prévu. En mode binaire, cela est traduit en CR suivi d'une valeur magique que pourrait ne pas être LF - peut-être pas ce que nous voulions.
  • \x0A est le moyen le plus portable d'indiquer un ASCII LF, mais vous ne souhaitez le faire qu'en mode binaire. La plupart des implémentations en mode texte traiteront cela comme \n.
89
Adrian McCarthy
  • "\ r" => Retour
  • "\ n" => Newline ou Linefeed (sémantique)

  • Les systèmes 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 antérieur à OS X, etc.)
10
NoMoreZealots

En bref,\r a ASCII valeur 13 (CR) et\n a ASCII valeur 10 (LF). Mac utilise CR comme séparateur de ligne (du moins, ce qui était le cas auparavant, je ne suis pas sûr pour les macs modernes), * nix utilise LF et Windows utilise les deux (CRLF).

4
Josip Medved

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

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

Produit cette sortie:

hai

\n est pour la nouvelle ligne.

4
DAYA PHILIP

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

Traditionnellement, Windows utilisait\r\n, Unix\n et Mac\r, mais les nouveaux Mac utilisent\n comme nuls.

3
Greg

\ r est le retour chariot;\n est une nouvelle ligne (saut de ligne) ... dépend du système d’exploitation. Lisez ceci article pour en savoir plus sur la différence entre '\ n' et '\ r\n' ... en C.

2
Nathan Loding

en C #, ils ont utilisé\r\n dans une chaîne.

2
wesley

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

1
Manjeet Kumar